27
frontend/.editorconfig
Normal file
@@ -0,0 +1,27 @@
|
||||
[*]
|
||||
charset=utf-8
|
||||
end_of_line=lf
|
||||
insert_final_newline=false
|
||||
indent_style=space
|
||||
indent_size=4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{.eslintrc,.babelrc,.stylelintrc,jest.config,*.json,*.jsb3,*.jsb2,*.bowerrc}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.less]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.scss]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.styl]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.analysis_options,*.yml,*.yaml}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
6
frontend/.env.development.local.example
Normal file
@@ -0,0 +1,6 @@
|
||||
VUE_APP_ENV=development
|
||||
VUE_APP_ROOT_API=http://development
|
||||
VUE_APP_WS_APP_KEY=1
|
||||
VUE_APP_WS_HOST=127.0.0.1
|
||||
VUE_APP_WS_PORT=6001
|
||||
VUE_APP_DNS={"foo.com.br": "https://api-foo.com.br", "bar.com.br": "https://api-bar.com.br"}
|
||||
6
frontend/.env.production.local.example
Normal file
@@ -0,0 +1,6 @@
|
||||
VUE_APP_ENV=production
|
||||
VUE_APP_ROOT_API=http://production
|
||||
VUE_APP_WS_APP_KEY=1
|
||||
VUE_APP_WS_HOST=127.0.0.1
|
||||
VUE_APP_WS_PORT=6001
|
||||
VUE_APP_DNS={"foo.com.br": "https://api-foo.com.br", "bar.com.br": "https://api-bar.com.br"}
|
||||
6
frontend/.env.test.local.example
Normal file
@@ -0,0 +1,6 @@
|
||||
VUE_APP_ENV=test
|
||||
VUE_APP_ROOT_API=http://test
|
||||
VUE_APP_WS_APP_KEY=1
|
||||
VUE_APP_WS_HOST=127.0.0.1
|
||||
VUE_APP_WS_PORT=6001
|
||||
VUE_APP_DNS={"foo.com.br": "https://api-foo.com.br", "bar.com.br": "https://api-bar.com.br"}
|
||||
24
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
.vs
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
jsconfig.json
|
||||
vue.config.js
|
||||
5
frontend/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
13841
frontend/package-lock.json
generated
Normal file
76
frontend/package.json
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"name": "conectasus2frontend",
|
||||
"version": "2.59.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vue-cli-service build --no-clean",
|
||||
"dev": "vue-cli-service build --mode development",
|
||||
"lint": "vue-cli-service lint",
|
||||
"serve": "vue-cli-service serve",
|
||||
"watch": "vue-cli-service build --mode development --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.3",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.3",
|
||||
"@fortawesome/vue-fontawesome": "^2.0.2",
|
||||
"axios": "^0.19.0",
|
||||
"bootstrap": "^4.5.3",
|
||||
"bootstrap-vue": "^2.21.2",
|
||||
"chart.js": "^3.8.2",
|
||||
"cleave.js": "^1.6.0",
|
||||
"core-js": "^3.6.5",
|
||||
"jsbarcode": "^3.11.5",
|
||||
"leaflet": "^1.9.4",
|
||||
"moment": "^2.24.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"text-mask-addons": "^3.8.0",
|
||||
"v-calendar": "^2.4.0",
|
||||
"v-mask": "^2.0.2",
|
||||
"v-money": "^0.8.1",
|
||||
"validator": "^13.6.0",
|
||||
"vee-validate": "^3.4.5",
|
||||
"vue": "^2.6.11",
|
||||
"vue-chartjs": "^4.1.2",
|
||||
"vue-element-loading": "^1.1.1",
|
||||
"vue-form-wizard": "^0.8.4",
|
||||
"vue-router": "^3.1.2",
|
||||
"vue-sticky-directive": "0.0.8",
|
||||
"vue2-editor": "^2.10.3",
|
||||
"vue2-leaflet": "^2.7.1",
|
||||
"vuex": "^3.1.1",
|
||||
"web-pki": "^2.15.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"pusher-js": "^7.0.1",
|
||||
"sass": "^1.35.1",
|
||||
"sass-loader": "^10.0.0",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
||||
11
frontend/public/config.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// Placeholder de desenvolvimento.
|
||||
//
|
||||
// Este arquivo e copiado verbatim para o dist (nao passa pelo webpack). No
|
||||
// container ele e SOBRESCRITO pelo entrypoint com o /var/www/frontend/config.js
|
||||
// montado no deploy, que carrega os valores do ambiente.
|
||||
//
|
||||
// Vazio de proposito: com ele assim, `npm run serve` cai no fallback para as
|
||||
// VUE_APP_* do .env.<modo>.local e o desenvolvimento local segue igual.
|
||||
//
|
||||
// O modelo a preencher no deploy esta em docker/config.js.example.
|
||||
window.__APP_CONFIG__ = {}
|
||||
BIN
frontend/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
23
frontend/public/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>ConectaSUS 2</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||
|
||||
<!-- Config de runtime. Precisa vir ANTES do bundle (que o vue-cli
|
||||
injeta no fim do body) porque define window.__APP_CONFIG__, lido
|
||||
por src/config.js. Trocado por ambiente no deploy, sem rebuild. -->
|
||||
<script src="<%= BASE_URL %>config.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but ArchitectUI doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
28
frontend/src/App.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<rkm-notification />
|
||||
|
||||
<component :is="layout">
|
||||
<transition name="fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
layout() {
|
||||
return (this.$route.meta.layout || 'logged') + '-layout'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "assets/styles/custom.scss";
|
||||
</style>
|
||||
199
frontend/src/Layout/Components/Header.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-navbar
|
||||
:open="true"
|
||||
class="rkm-navbar"
|
||||
>
|
||||
<rkm-navbar-nav-icon @click="$emit('toggle')" />
|
||||
|
||||
<rkm-navbar-brand class="ml-3">
|
||||
<span>ConectaSUS</span> <span>v{{ packageJSON.version }}</span>
|
||||
|
||||
<rkm-navbar-nav-release-notes-button
|
||||
:quantidade-notas-versao-novas="quantidadeNotasVersaoNovas"
|
||||
@click="$refs.ModalNotaVersao.open()"
|
||||
class="ml-2"
|
||||
/>
|
||||
</rkm-navbar-brand>
|
||||
|
||||
<rkm-navbar-brand class="ml-auto">
|
||||
<rkm-navbar-nav-notification-button
|
||||
:quantidade-notificacoes-nao-lidas="quantidadeNotificacoesNaoLidas"
|
||||
@click="$refs.ModalNotificacao.open()"
|
||||
/>
|
||||
</rkm-navbar-brand>
|
||||
|
||||
<rkm-navbar-nav class="rkm-navbar-nav">
|
||||
<rkm-nav-item-dropdown right>
|
||||
<template slot="button-content">
|
||||
<rkm-icon :icon="['far', 'user-circle']" /> {{ autenticacao.usuario.cidadao.nome }}
|
||||
</template>
|
||||
|
||||
<rkm-dropdown-group>
|
||||
<rkm-dropdown-header>Você está logado como:</rkm-dropdown-header>
|
||||
|
||||
<rkm-dropdown-text>
|
||||
<strong>Unidade: </strong> <span>{{ autenticacao.lotacao && autenticacao.lotacao.infraestrutura.unidade.nomeFantasia }}</span>
|
||||
</rkm-dropdown-text>
|
||||
<rkm-dropdown-text>
|
||||
<strong>Local de atendimento: </strong> <span>{{ autenticacao.lotacao && autenticacao.lotacao.infraestrutura.nome }}</span>
|
||||
</rkm-dropdown-text>
|
||||
<rkm-dropdown-text>
|
||||
<strong>CBO: </strong> <span>{{ autenticacao.lotacao && autenticacao.lotacao.ocupacao.nome }}</span>
|
||||
</rkm-dropdown-text>
|
||||
<rkm-dropdown-text v-if="autenticacao.usuario.registroTipo && autenticacao.usuario.registroNumero">
|
||||
<strong>{{ autenticacao.usuario.registroTipoId == enums.tipoRegistro.OUTRO
|
||||
? autenticacao.usuario.registroTipoOutro
|
||||
: autenticacao.usuario.registroTipo.sigla }}: </strong> <span>{{ autenticacao.usuario.registroNumero }}</span>
|
||||
</rkm-dropdown-text>
|
||||
<rkm-dropdown-text>
|
||||
<strong>Setor: </strong> <span>{{ autenticacao.centroCusto && autenticacao.centroCusto.setor.nome }}</span>
|
||||
</rkm-dropdown-text>
|
||||
</rkm-dropdown-group>
|
||||
|
||||
<rkm-dropdown-divider />
|
||||
|
||||
<rkm-dropdown-item to="/lotacao">
|
||||
<rkm-icon icon="sync-alt" /> Trocar lotação
|
||||
</rkm-dropdown-item>
|
||||
|
||||
<rkm-dropdown-item to="/cadastro/usuario-perfil">
|
||||
<rkm-icon :icon="['far', 'user-circle']" /> Meu perfil
|
||||
</rkm-dropdown-item>
|
||||
|
||||
<rkm-dropdown-divider />
|
||||
|
||||
<rkm-dropdown-item
|
||||
@click="handleLogout"
|
||||
color="danger"
|
||||
>
|
||||
<rkm-icon icon="door-open" /> Sair do sistema
|
||||
</rkm-dropdown-item>
|
||||
</rkm-nav-item-dropdown>
|
||||
</rkm-navbar-nav>
|
||||
</rkm-navbar>
|
||||
|
||||
<ModalNotaVersao ref="ModalNotaVersao" />
|
||||
<ModalNotificacao ref="ModalNotificacao" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import ModalNotaVersao from '@/components/intranet/cadastro/nota-versao/Modal'
|
||||
import ModalNotificacao from '@/components/administracao/notificacao/Modal'
|
||||
|
||||
// Mixins.
|
||||
import { repository } from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import packageJSON from '/package.json'
|
||||
|
||||
// Vuex.
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
|
||||
import tipoRegistro from '@/enums/cadastro/usuario/tipoRegistro'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModalNotaVersao,
|
||||
ModalNotificacao,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
autenticacao: 'getAutenticacao',
|
||||
centroCusto: 'getCentroCusto',
|
||||
lotacao: 'getLotacao',
|
||||
quantidadeNotasVersaoNovas: 'getQuantidadeNotasVersaoNovas',
|
||||
quantidadeNotificacoesNaoLidas: 'getQuantidadeNotificacoesNaoLidas',
|
||||
}),
|
||||
},
|
||||
created() {
|
||||
this.packageJSON = packageJSON
|
||||
this.repositories = {
|
||||
autenticacao: this.getConectaSusRepository('administracao.autenticacao')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
logout: null,
|
||||
notification: null,
|
||||
packageJSON: null,
|
||||
enums: { tipoRegistro }
|
||||
}),
|
||||
methods: {
|
||||
...mapActions([
|
||||
'clear',
|
||||
'setAutenticacao',
|
||||
'unsetShowExitFormConfirmation',
|
||||
]),
|
||||
...mapActions('notification', ['setNotification']),
|
||||
handleExpirationToken() {
|
||||
if (this.autenticacao.expiration > 0) {
|
||||
const date = new Date()
|
||||
const expiration = new Date(this.autenticacao.expiration * 1000)
|
||||
const diff = ((expiration.getTime() - date.getTime()))
|
||||
|
||||
if ((diff - (300 * 1000)) > 0) {
|
||||
this.notification = setTimeout(() => {
|
||||
this.showWarningConfirmation(
|
||||
'Expiração da sessão',
|
||||
`A sessão vai expirar em 5 minutos, deseja atualizar a sessão?`,
|
||||
async () => this.handleRefreshToken(),
|
||||
)
|
||||
}, diff - (300 * 1000))
|
||||
}
|
||||
|
||||
this.logout = setTimeout(() => {
|
||||
this.clear()
|
||||
.then(customer => {
|
||||
this.unsetShowExitFormConfirmation()
|
||||
this.$router.push({ name: 'login', params: { customer: customer.link }})
|
||||
this.setNotification({ visible: false })
|
||||
})
|
||||
}, diff)
|
||||
}
|
||||
},
|
||||
handleLogout() {
|
||||
this.clearTimeouts()
|
||||
this.repositories.autenticacao.logout()
|
||||
.catch(this.handleError)
|
||||
.finally(() => {
|
||||
this.clear()
|
||||
.then(customer => {
|
||||
this.unsetShowExitFormConfirmation()
|
||||
this.$router.push({ name: 'login', params: { customer: customer.link }})
|
||||
})
|
||||
})
|
||||
},
|
||||
handleRefreshToken() {
|
||||
this.clearTimeouts()
|
||||
this.repositories.autenticacao.refresh({
|
||||
centro_custo_id: this.centroCusto.id,
|
||||
lotacao_id: this.lotacao.id,
|
||||
})
|
||||
.then(({data}) => {
|
||||
this.setAutenticacao(data)
|
||||
this.handleExpirationToken()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
},
|
||||
clearTimeouts() {
|
||||
clearTimeout(this.notification)
|
||||
clearTimeout(this.logout)
|
||||
}
|
||||
},
|
||||
mixins: [ repository ],
|
||||
mounted() {
|
||||
this.handleExpirationToken()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.rkm-navbar {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
.rkm-navbar-nav >>> .nav-link {
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
66
frontend/src/Layout/Components/Sidebar.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<rkm-sidebar :open="open">
|
||||
<rkm-sidebar-list>
|
||||
<rkm-sidebar-list-group>
|
||||
<rkm-sidebar-list-group-item
|
||||
:active="$route.path && $route.path.includes('dashboard')"
|
||||
icon="home"
|
||||
title="Dashboard"
|
||||
to="/"
|
||||
/>
|
||||
</rkm-sidebar-list-group>
|
||||
|
||||
<sidebar-item :items="items" />
|
||||
</rkm-sidebar-list>
|
||||
|
||||
<div class="footer">
|
||||
<div>ConectaSUS ⋅ {{ others.moment().format('YYYY') }}</div>
|
||||
|
||||
<div>
|
||||
<rkm-icon :icon="['far', 'clock']" /> {{ others.moment().format('DD/MM/YYYY HH:mm\\h') }}
|
||||
</div>
|
||||
</div>
|
||||
</rkm-sidebar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import SidebarItem from './SidebarItem.vue'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: { SidebarItem },
|
||||
computed: {
|
||||
...mapGetters(['getMenu']),
|
||||
items() {
|
||||
return this.getMenu
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
modulos: [],
|
||||
others: { moment },
|
||||
}),
|
||||
props: {
|
||||
open: { type: Boolean },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.footer {
|
||||
background: rgba(0,0,0,0.1);
|
||||
border-radius: 100px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 60px;
|
||||
justify-content: space-evenly;
|
||||
margin: 0.75rem;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
49
frontend/src/Layout/Components/SidebarItem.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-sidebar-list-group
|
||||
v-for="item in items"
|
||||
v-bind:key="item.id"
|
||||
class="sidebar-list-group"
|
||||
>
|
||||
<rkm-sidebar-list-group-item
|
||||
:active="`/${$route.path.split('/')[1]}/${$route.path.split('/')[2]}` == item.link"
|
||||
:icon="item.icone && item.icone.split('/')"
|
||||
:title="item.nome"
|
||||
:to="item.link"
|
||||
class="sidebar-list-group-item"
|
||||
/>
|
||||
|
||||
<rkm-sidebar-list
|
||||
v-if="item.items"
|
||||
class="sidebar-list"
|
||||
sub-group
|
||||
>
|
||||
<sidebar-item :items="item.items" />
|
||||
</rkm-sidebar-list>
|
||||
</rkm-sidebar-list-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SidebarItem',
|
||||
props: {
|
||||
items: { type: Array },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$primary: #007bff;
|
||||
|
||||
.sidebar-list {
|
||||
transition: 0.02s 0.02s;
|
||||
visibility: hidden;
|
||||
}
|
||||
.sidebar-list-group:hover > .sidebar-list-group-item {
|
||||
color: darken($primary, 10%) !important;
|
||||
}
|
||||
.sidebar-list-group:hover > .sidebar-list {
|
||||
visibility: visible;
|
||||
}
|
||||
</style>
|
||||
5
frontend/src/Layout/Wrappers/emptyLayout.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
206
frontend/src/Layout/Wrappers/loggedLayout.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<rkm-application>
|
||||
<template v-if="autenticado">
|
||||
<Header @toggle="handleToggle" />
|
||||
|
||||
<Sidebar :open="open" />
|
||||
|
||||
<rkm-main :open="open">
|
||||
<slot />
|
||||
</rkm-main>
|
||||
|
||||
<rkm-toast
|
||||
v-model="exportacaoBpa.visible"
|
||||
color="success"
|
||||
no-auto-hide
|
||||
solid
|
||||
title="BPA - Exportação"
|
||||
>
|
||||
O arquivo <a href="#" @click.prevent="handleExportacaoBpaDownload(exportacaoBpa.id)">{{ exportacaoBpa.arquivo }}</a> está pronto para download.
|
||||
</rkm-toast>
|
||||
|
||||
<rkm-toast
|
||||
v-model="exportacaoEsus.visible"
|
||||
color="success"
|
||||
no-auto-hide
|
||||
solid
|
||||
title="Atenção básica - Exportação"
|
||||
>
|
||||
O arquivo <a href="#" @click.prevent="handleExportacaoEsusDownload(exportacaoEsus.id)">{{ exportacaoEsus.arquivo }}</a> está pronto para download.
|
||||
</rkm-toast>
|
||||
</template>
|
||||
</rkm-application>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import Header from '@/Layout/Components/Header'
|
||||
import Sidebar from '@/Layout/Components/Sidebar'
|
||||
|
||||
// Mixins.
|
||||
import { file, repository } from '@/mixins'
|
||||
|
||||
// Vuex.
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
|
||||
// Others.
|
||||
import Pusher from 'pusher-js'
|
||||
import config from '@/config'
|
||||
import { repositoryFactory } from '@/repositories/repositoryFactory'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Header,
|
||||
Sidebar,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
autenticacao: 'getAutenticacao',
|
||||
customer: 'getCustomer',
|
||||
exportacaoBpaEmAndamento: 'getExportacaoBpaEmAndamento',
|
||||
exportacaoEsusEmAndamento: 'getExportacaoEsusEmAndamento',
|
||||
lotacao: 'getLotacao',
|
||||
open: 'getSidebar',
|
||||
}),
|
||||
autenticado() {
|
||||
return this.autenticacao
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
exportacaoBpa: this.getConectaSusRepository('bpa.exportacao'),
|
||||
exportacaoEsus: this.getConectaSusRepository('atencaoBasica.exportacao'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data: () => ({
|
||||
exportacaoBpa: {
|
||||
id: null,
|
||||
arquivo: null,
|
||||
visible: false,
|
||||
},
|
||||
exportacaoEsus: {
|
||||
id: null,
|
||||
arquivo: null,
|
||||
visible: false,
|
||||
},
|
||||
pusher: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions([
|
||||
'setExportacaoBpaEmAndamento',
|
||||
'setExportacaoEsusEmAndamento',
|
||||
'setLoading',
|
||||
'setSidebar',
|
||||
'unsetLoading',
|
||||
]),
|
||||
init() {
|
||||
this.connect()
|
||||
|
||||
if (this.exportacaoBpaEmAndamento) {
|
||||
this.pusher.subscribe(`private-${this.customer.link}-bpa-exportacao-finalizada-usuario.${this.lotacao.usuarioId}`)
|
||||
.bind('ExportacaoFinalizada', (data) => {
|
||||
this.exportacaoBpa.id = data.exportacaoId
|
||||
this.exportacaoBpa.arquivo = data.exportacaoArquivo
|
||||
this.exportacaoBpa.visible = true
|
||||
this.setExportacaoBpaEmAndamento(false)
|
||||
})
|
||||
}
|
||||
|
||||
if (this.exportacaoEsusEmAndamento) {
|
||||
this.pusher.subscribe(`private-${this.customer.link}-atencao-basica-exportacao-finalizada-usuario.${this.lotacao.usuarioId}`)
|
||||
.bind('ExportacaoFinalizada', (data) => {
|
||||
this.exportacaoEsus.id = data.exportacaoArquivoId
|
||||
this.exportacaoEsus.arquivo = data.exportacaoArquivoNome
|
||||
this.exportacaoEsus.visible = true
|
||||
this.setExportacaoEsusEmAndamento(false)
|
||||
})
|
||||
}
|
||||
},
|
||||
load() {
|
||||
if (this.exportacaoBpaEmAndamento || this.exportacaoEsusEmAndamento) {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
handleToggle() {
|
||||
this.setSidebar(!this.open)
|
||||
},
|
||||
handleExportacaoBpaDownload(id) {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.exportacaoBpa.download(id)
|
||||
.then(response => {
|
||||
const file = response.headers['content-disposition'].split('filename=')[1]
|
||||
const blob = new Blob([response.data])
|
||||
const link = document.createElement('a')
|
||||
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.download = file
|
||||
link.click()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleExportacaoEsusDownload(id) {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.exportacaoEsus.download(id)
|
||||
.then(response => {
|
||||
const file = response.headers['content-disposition'].split('filename=')[1]
|
||||
const blob = new Blob([response.data])
|
||||
const link = document.createElement('a')
|
||||
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.download = file
|
||||
link.click()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
connect() {
|
||||
if (this.pusher === null) {
|
||||
this.pusher = new Pusher(config.WS_APP_KEY, {
|
||||
wsHost: config.WS_HOST,
|
||||
wsPort: config.WS_PORT,
|
||||
forceTLS: false,
|
||||
enabledTransports: ['ws'],
|
||||
authorizer: (channel) => ({
|
||||
authorize: (socketId, callback) => {
|
||||
const repository = repositoryFactory.get('conectaSus.websocket')
|
||||
|
||||
repository.login({
|
||||
token: socketId + ':' + channel.name
|
||||
})
|
||||
.then(response => callback(null, { auth: response }))
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
disconnect() {
|
||||
if (this.pusher) {
|
||||
this.pusher.disconnect()
|
||||
this.pusher = null
|
||||
}
|
||||
},
|
||||
handlePusherConnection() {
|
||||
if (this.exportacaoBpaEmAndamento || this.exportacaoEsusEmAndamento) {
|
||||
this.init()
|
||||
} else {
|
||||
this.disconnect()
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [file, repository],
|
||||
watch: {
|
||||
exportacaoBpaEmAndamento() {
|
||||
this.handlePusherConnection()
|
||||
},
|
||||
exportacaoEsusEmAndamento() {
|
||||
this.handlePusherConnection()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
226
frontend/src/Layout/Wrappers/loginLayout.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div id="body">
|
||||
<div id="content">
|
||||
<div id="content-inner">
|
||||
<div class="login-container">
|
||||
<rkm-col class="login-aside">
|
||||
<div class="wallpaper">
|
||||
<div class="aside-content">
|
||||
<div class="aside-title">ConectaSUS ⋅ Sistema de Gestão de Saúde Pública</div>
|
||||
<div class="aside-city">{{customer ? customer.nome : null}}</div>
|
||||
<div class="aside-actions">
|
||||
<rkm-button><rkm-icon icon="headset" /> Dificuldade pra entrar? Pedir ajuda</rkm-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</rkm-col>
|
||||
<rkm-col class="login-right">
|
||||
<div class="login-header">
|
||||
<img
|
||||
:src="customer && customer.logotipo ? require(`@/assets/cliente/logotipo/${customer.logotipo}`) : null"
|
||||
width="140"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
|
||||
<div class="login-footer">
|
||||
<div
|
||||
v-if="customer && (!customer.ativo || customer.motivoInativacao)"
|
||||
class="motivo-inativacao"
|
||||
>
|
||||
{{customer.motivoInativacao}}
|
||||
</div>
|
||||
</div>
|
||||
</rkm-col>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({customer: 'getCustomer'}),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
justify-content: space-evenly;
|
||||
box-shadow: -10px 0px 70px -80px rgb(0 0 0 / 50%) inset;
|
||||
background: var(--primary) url('~@/assets/images/login/medical-2.jpg');
|
||||
background-blend-mode: multiply;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.login-container:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.login-aside {
|
||||
flex: 0 1 auto;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
.aside-actions .btn {
|
||||
background: rgb(255 255 255 / 21%);
|
||||
border: none;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem;
|
||||
position: relative;
|
||||
height: auto;
|
||||
color: #FFF;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.aside-title {
|
||||
font-weight: 600;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.aside-city {
|
||||
font-weight: 100;
|
||||
font-size: 4.5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.aside-content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.aside-actions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wallpaper {
|
||||
color: #FFF;
|
||||
font-size: 2rem;
|
||||
line-height: 1.2;
|
||||
text-shadow: 0.5px 0.5px #282a2c;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.login-right {
|
||||
align-self: start;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
background: #FFF;
|
||||
flex-direction: column;
|
||||
flex: 0 1 auto;
|
||||
padding: 0;
|
||||
margin: 3rem 0;
|
||||
width: auto;
|
||||
border-radius: 2rem;
|
||||
height: calc(100% - 6rem);
|
||||
width: 35vw;
|
||||
}
|
||||
|
||||
#body >>> .login-right > * {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-header {
|
||||
width: 100%;
|
||||
padding: 60px 10px 10px 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.07);
|
||||
padding: 10px 5px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.motivo-inativacao {
|
||||
color: red;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn svg {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#body >>> .login-form h1 {
|
||||
font-size: 1.8rem;
|
||||
line-height: 1;
|
||||
margin-bottom: 2rem;
|
||||
font-weight: 400;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
#body >>> .login-form h1 span {
|
||||
color: var(--primary);
|
||||
font-weight: 200;
|
||||
text-transform: initial;
|
||||
letter-spacing: 0px;
|
||||
}
|
||||
|
||||
#body >>> .login-form-actions .btn[type="submit"] {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#body >>> .login-form-actions .btn[type="submit"] {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 100px;
|
||||
padding: 0.7rem;
|
||||
}
|
||||
|
||||
#body >>> .login-form-actions .btn[type="submit"] + .btn {
|
||||
background: none;
|
||||
color: var(--gray);
|
||||
margin: 0.5rem 0 0 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
display: block;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#body >>> .login-form {
|
||||
padding: 0 60px;
|
||||
}
|
||||
|
||||
#body >>> h5 {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
#body >>> h6 {
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
margin: 6px 0 0 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
74
frontend/src/Layout/Wrappers/portalLayout.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div id="body">
|
||||
<div id="content">
|
||||
<div id="content-inner">
|
||||
<rkm-application>
|
||||
<template>
|
||||
<rkm-navbar
|
||||
:open="true"
|
||||
class="rkm-navbar"
|
||||
>
|
||||
<rkm-navbar-brand class="ml-3">
|
||||
<span>ConectaSUS</span>
|
||||
</rkm-navbar-brand>
|
||||
</rkm-navbar>
|
||||
|
||||
<rkm-main :open="open">
|
||||
<slot />
|
||||
</rkm-main>
|
||||
</template>
|
||||
</rkm-application>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// Mixins.
|
||||
import { repository } from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import packageJSON from '/package.json'
|
||||
|
||||
// Vuex.
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({
|
||||
open: 'getSidebar',
|
||||
}),
|
||||
},
|
||||
created() {
|
||||
this.packageJSON = packageJSON
|
||||
|
||||
},
|
||||
data: () => ({
|
||||
packageJSON: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions([
|
||||
'setSidebar',
|
||||
]),
|
||||
handleToggle() {
|
||||
this.setSidebar(!this.open)
|
||||
},
|
||||
},
|
||||
mixins: [repository],
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.rkm-navbar {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
.rkm-navbar-nav >>> .nav-link {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.rkm-main {
|
||||
padding-left: 0!important;
|
||||
}
|
||||
|
||||
</style>
|
||||
74
frontend/src/Layout/Wrappers/regulacaoDivulgacaoLayout.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div id="body">
|
||||
<div id="content">
|
||||
<div id="content-inner">
|
||||
<rkm-application>
|
||||
<template>
|
||||
<rkm-navbar
|
||||
:open="true"
|
||||
class="rkm-navbar"
|
||||
>
|
||||
<rkm-navbar-brand class="ml-3">
|
||||
<span>ConectaSUS</span>
|
||||
</rkm-navbar-brand>
|
||||
</rkm-navbar>
|
||||
|
||||
<rkm-main :open="open">
|
||||
<slot />
|
||||
</rkm-main>
|
||||
</template>
|
||||
</rkm-application>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// Mixins.
|
||||
import { repository } from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import packageJSON from '/package.json'
|
||||
|
||||
// Vuex.
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({
|
||||
open: 'getSidebar',
|
||||
}),
|
||||
},
|
||||
created() {
|
||||
this.packageJSON = packageJSON
|
||||
|
||||
},
|
||||
data: () => ({
|
||||
packageJSON: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions([
|
||||
'setSidebar',
|
||||
]),
|
||||
handleToggle() {
|
||||
this.setSidebar(!this.open)
|
||||
},
|
||||
},
|
||||
mixins: [repository],
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.rkm-navbar {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
.rkm-navbar-nav >>> .nav-link {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.rkm-main {
|
||||
padding-left: 0!important;
|
||||
}
|
||||
|
||||
</style>
|
||||
BIN
frontend/src/assets/cliente/logotipo/anhembi.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
frontend/src/assets/cliente/logotipo/aparecida.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
frontend/src/assets/cliente/logotipo/barrabonita.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
frontend/src/assets/cliente/logotipo/biritibamirim.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
frontend/src/assets/cliente/logotipo/brotas.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
frontend/src/assets/cliente/logotipo/cabreuva.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
frontend/src/assets/cliente/logotipo/cachoeirapaulista.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
frontend/src/assets/cliente/logotipo/caconde.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
frontend/src/assets/cliente/logotipo/conectasus.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
frontend/src/assets/cliente/logotipo/corumbatai.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
frontend/src/assets/cliente/logotipo/cubatao.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
frontend/src/assets/cliente/logotipo/demo.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
frontend/src/assets/cliente/logotipo/descalvado.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
frontend/src/assets/cliente/logotipo/igaracu.png
Normal file
|
After Width: | Height: | Size: 410 KiB |
BIN
frontend/src/assets/cliente/logotipo/iracemapolis.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
frontend/src/assets/cliente/logotipo/itapeva.jpeg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
frontend/src/assets/cliente/logotipo/itapevi.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
frontend/src/assets/cliente/logotipo/itapolis.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
frontend/src/assets/cliente/logotipo/itirapina.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
frontend/src/assets/cliente/logotipo/ituverava.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
frontend/src/assets/cliente/logotipo/jardinopolis.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
frontend/src/assets/cliente/logotipo/macatuba.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
frontend/src/assets/cliente/logotipo/mairipora.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
frontend/src/assets/cliente/logotipo/mococa.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
frontend/src/assets/cliente/logotipo/muzambinho.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
frontend/src/assets/cliente/logotipo/pardinho.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
frontend/src/assets/cliente/logotipo/pederneiras.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
frontend/src/assets/cliente/logotipo/pirassununga.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
frontend/src/assets/cliente/logotipo/portoferreira.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
frontend/src/assets/cliente/logotipo/ribeiraobonito.png
Normal file
|
After Width: | Height: | Size: 518 KiB |
BIN
frontend/src/assets/cliente/logotipo/santaritapassa.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
frontend/src/assets/cliente/logotipo/santoantoniojardim.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
frontend/src/assets/cliente/logotipo/ssgrama.png
Normal file
|
After Width: | Height: | Size: 202 KiB |
BIN
frontend/src/assets/cliente/logotipo/stoantoniodaalegria.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
frontend/src/assets/cliente/logotipo/tapiratiba.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
449
frontend/src/assets/images/dashboard/calendario.svg
Normal file
@@ -0,0 +1,449 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="727px" height="638px" viewBox="0 0 727 638" enable-background="new 0 0 727 638" xml:space="preserve"> <image id="image0" width="727" height="638" x="0" y="0"
|
||||
href="data:image/png;base64,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
|
||||
Z9AlZf9PjiqHDVfsyvV69L5bHCuDAADQnQjXAPqcwNjH9bePrG4FAKA/Ys41AAAAYBLCNQAAAGAS
|
||||
wjUAAABgEsI1AAAAYBLCNQAAAGASwjUAAABgEsI1AAAAYBLCNQAAAGASwjUAAABgEsI1AAAAYBLC
|
||||
NQAAAGASwjUAAABgEo+OFqy5VGF1WwEAAAC31uFw7R8QaHVbAQAAgJ53vqrDRZkWAgAAAJiEcA0A
|
||||
AACYhHANAAAAmIRwDQAAAJiEcA0AAACYhHANAAAAmKTDS/EBANzL5/v+V5+VSd7jbtAPp42wujlA
|
||||
j2v2Gjh/RH/5tEzV8tUtCyJ1k9UN7HNO6MPdhSqWhybc9h1F87bTIsI1upH9RcibHADAXGcP/kOf
|
||||
lRHy4H4I1+g+56tUaXUbgD7sppnf40sr+qnzKvGbpHsXkKrhfnp5uD6v7IyjOlnTuCc4/Hu68/qW
|
||||
jrmOnp49+A99fOqKJMl73FiNOl+okzXOt0eXfJ2rN/MvGRuX9Nnu/9WX9p/tXI45/6Tt9HPTOC+d
|
||||
PHWJn7tN0Ob/9WHNf0J1lB8+VvfODGvWXxKvE3PY/79Lkq9uCZc+y78keQ3X7XFTNcr+vNu31fwn
|
||||
cKaFmOkaPk8cUxAa+6Dx9cYvdl3W9L3HeC3I6T3ts/yjUmtTFJz6x/l1hM6xv89IUnD42BZKOL+X
|
||||
2cs1fkY4v09NuXTUqMv2+ghy+XzqO+9jvfqExs/3ub4RNjqhD3c3PXZJn2Uc0Vm5hg1Jqj5V2Eo9
|
||||
MNvZg/9oFtSqTx3Vh18777mik6cudapetMyM/+tnK5vfoDj/H8o+b/Wj682afhhdsgVrWOaaPk9G
|
||||
TNUPw30lSdWnTulznVDeqSuyhT2CdZecP6K/tPKaKLl0pcmeKzr5aa4+d9l3SZ/Zg7Uk1ZTp430n
|
||||
rH5UvY5zsJak4nzXEK3zR/SXJsHaVu5/m3yu2z7rG+u6pM8y/qFsl8+nU036sPfq5SPXhqbfSL8u
|
||||
t3W0Y7991OGijp8/L51v8i3J+dstzHF9pO5tNip6XtkZtufe8a3WGJkoPntCchoJ7UvfYK1zXseb
|
||||
/l9vYYShPaOmfUf3Tmus0/ZauqJLFyTRRdfG/h7V0i8GsFanPk+kUddH6paz/6vPyi7ps922MOg9
|
||||
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
|
||||
p5QAAAAASUVORK5CYII=" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 34 KiB |
1
frontend/src/assets/images/dashboard/medicina.svg
Normal file
|
After Width: | Height: | Size: 45 KiB |
1
frontend/src/assets/images/error/empty.svg
Normal file
|
After Width: | Height: | Size: 34 KiB |
1
frontend/src/assets/images/login/computer.svg
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
frontend/src/assets/images/login/enfeite.png
Normal file
|
After Width: | Height: | Size: 466 KiB |
BIN
frontend/src/assets/images/login/medical-1.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
frontend/src/assets/images/login/medical-2.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
frontend/src/assets/images/login/piracicaba-1.jpg
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
frontend/src/assets/images/login/piracicaba-2.jpg
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
frontend/src/assets/outros/cartao-nacional-saude.png
Normal file
|
After Width: | Height: | Size: 971 KiB |
BIN
frontend/src/assets/sounds/painel-senha/tela/efeito.wav
Normal file
71
frontend/src/assets/styles/_custom.scss
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
@import "bootstrap/override";
|
||||
@import "pronto-atendimento/classificacao-risco";
|
||||
@import "pronto-atendimento/atendimento-medico";
|
||||
|
||||
$labelHeight: 30px;
|
||||
|
||||
* {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 15px;
|
||||
background: #eeeeef;
|
||||
}
|
||||
|
||||
h4, h5 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 200;
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.modal > div {
|
||||
width: 100%;
|
||||
transition: max-width 0.5s !important;
|
||||
}
|
||||
|
||||
.col-min {
|
||||
width: 1%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.placeholder-label:not(.btn) {
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
.placeholder-label.form-group-radio,
|
||||
.placeholder-label.form-group-checkbox,
|
||||
.placeholder-label.custom-radio,
|
||||
.placeholder-label.custom-checkbox {
|
||||
padding-top: $labelHeight;
|
||||
}
|
||||
|
||||
.form-group-radio .custom-control-label,
|
||||
.form-group-checkbox .custom-control-label,
|
||||
.custom-radio .custom-control-label,
|
||||
.custom-checkbox .custom-control-label {
|
||||
min-height: 25px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.form-group-radio-button-disabled,
|
||||
.form-group-checkbox-button-disabled {
|
||||
background-color: #e9ecef !important;
|
||||
|
||||
label {
|
||||
color: #495057 !important;
|
||||
border-color: #ced4da !important;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-label.btn {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
:not(.input-group):not(.btn-group) > .btn + .btn {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
444
frontend/src/assets/styles/bootstrap/_override.scss
Normal file
@@ -0,0 +1,444 @@
|
||||
$gap: 0.5rem;
|
||||
$paddingTable: 0.5rem;
|
||||
$fieldHeight: calc(1.313em + 0.75rem + 2px);
|
||||
|
||||
.row {
|
||||
margin-left: -$gap;
|
||||
margin-right: -$gap;
|
||||
}
|
||||
|
||||
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, .col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, .col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, .col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, .col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, .col-xl-auto {
|
||||
padding-left: $gap;
|
||||
padding-right: $gap;
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
padding: 0 1.75rem 0 0.5rem;
|
||||
}
|
||||
|
||||
.custom-control-inline:last-child,
|
||||
.custom-control-inline:only-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.form-control, .custom-select, .btn, .input-group-text {
|
||||
height: $fieldHeight;
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
min-height: calc(#{$fieldHeight} * 2);
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
line-height: 1.25;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn .b-icon.bi, .nav-link .b-icon.bi, .dropdown-toggle .b-icon.bi, .dropdown-item .b-icon.bi, .input-group-text .b-icon.bi {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-color: #dee2e6;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.card-body, .tab-content {
|
||||
padding: 0.75rem;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
.pagination .page-link {
|
||||
padding: 0.5rem 0.75rem;
|
||||
height: 35px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
font-size: 0.9rem;
|
||||
box-shadow: 3px 3px 8px -3px rgb(0 0 0 / 50%);
|
||||
}
|
||||
|
||||
.dropdown-header, .dropdown-item {
|
||||
padding: 0.5rem 1rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.b-dropdown-text {
|
||||
padding: 0.25rem 1rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
|
||||
body .table.b-table>tfoot>tr>[aria-sort=none], body .table.b-table>thead>tr>th[aria-sort=none]{ background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='black' opacity='.3' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='black' opacity='.3' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e")!important; }
|
||||
body .table.b-table>tfoot>tr>[aria-sort=ascending], body .table.b-table>thead>tr>th[aria-sort=ascending]{ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='%23007bff' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='black' opacity='.3' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e") !important; }
|
||||
body .table.b-table>tfoot>tr>[aria-sort=descending], body .table.b-table>thead>tr>th[aria-sort=descending]{ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='101' height='101' view-box='0 0 101 101' preserveAspectRatio='none'%3e%3cpath fill='black' opacity='.3' d='M51 1l25 23 24 22H1l25-22z'/%3e%3cpath fill='%23007bff' d='M51 101l25-23 24-22H1l25 22z'/%3e%3c/svg%3e") !important; }
|
||||
|
||||
.custom-control-label::before {
|
||||
top: 0.3rem;
|
||||
}
|
||||
|
||||
|
||||
.b-calendar .b-calendar-inner {
|
||||
min-width: auto;
|
||||
}
|
||||
.b-form-btn-label-control.btn-group > .dropdown-menu {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.b-calendar .b-calendar-grid {
|
||||
border: none;
|
||||
font-size: 0.9rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.b-calendar output {
|
||||
border: none;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px 4px 0 0;
|
||||
border-bottom: 1px solid #d0d0d0;
|
||||
line-height: 1;
|
||||
padding: 0.5rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.b-calendar-grid-body {
|
||||
flex-direction: column;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.b-calendar .b-calendar-grid-body .col[data-date] .btn {
|
||||
font-size: 12px;
|
||||
margin: 0 !important;
|
||||
width: auto;
|
||||
height: auto;
|
||||
flex: 1;
|
||||
font-weight: 500 !important;
|
||||
border-radius: 2px !important;
|
||||
}
|
||||
|
||||
.b-calendar-grid-weekdays {
|
||||
padding: 0 5px;
|
||||
}
|
||||
.b-calendar-grid-body, .b-calendar-grid-weekdays.row.no-gutters.border-bottom {
|
||||
display: flex;
|
||||
border: none !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.b-calendar .b-calendar-header, .b-calendar .b-calendar-nav {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.b-calendar.b-form-date-calendar.w-100 {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.b-calendar-grid-help {
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
line-height: 1;
|
||||
color: #333 !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b-calendar-grid-body .row {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.b-calendar .b-calendar-grid-body .col[data-date] {
|
||||
display: flex;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.b-calendar-grid-caption {
|
||||
text-transform: uppercase;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.b-calendar .btn.disabled {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.b-calendar .b-calendar-grid .btn:not(.active):hover {
|
||||
box-shadow: 0px 0px 0px 1px var(--primary) inset;
|
||||
color: var(--primary) !important;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.b-calendar .btn-outline-primary:not(:disabled):not(.disabled):active, .b-calendar .btn-outline-primary:not(:disabled):not(.disabled).active, .b-calendar .show > .btn-outline-primary.dropdown-toggle {
|
||||
color: #FFF !important;
|
||||
}
|
||||
|
||||
.b-calendar svg {
|
||||
transform: scale(0.8);
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.b-calendar .b-calendar-grid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.b-calendar-grid-caption {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.b-calendar-nav {
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #d0d0d0;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
}
|
||||
|
||||
.b-calendar-nav .btn {
|
||||
padding: 0;
|
||||
margin: 0 !important;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.b-calendar-nav .btn:hover {
|
||||
background: rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.b-calendar .btn.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.rkm-time-picker {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.rkm-time-picker .b-time {
|
||||
width: auto;
|
||||
min-width: auto;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.rkm-time-picker .mx-auto {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.rkm-time-picker svg.bi {
|
||||
transform: scale(0.9);
|
||||
font-size: 100% !important;
|
||||
}
|
||||
|
||||
.rkm-time-picker .b-form-spinbutton.b-time-hours + .d-flex svg {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.rkm-date-picker .b-form-spinbutton {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.rkm-time-picker .b-form-spinbutton {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rkm-time-picker .b-form-spinbutton .btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.rkm-time-picker .b-form-spinbutton output {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tabs {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
margin: 0;
|
||||
padding: 0 0.5rem;
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item a {
|
||||
padding: 1rem 0.75rem;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active, .nav-tabs .nav-item.show .nav-link {
|
||||
color: var(--primary);
|
||||
background: none;
|
||||
}
|
||||
|
||||
.tabs .card-header {
|
||||
padding: 0;
|
||||
background: #FFF;
|
||||
border-radius: 3px 3px 0 0;
|
||||
border-bottom-color: #dee2e6;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: none;
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
color: var(--gray);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 0.25rem;
|
||||
width: calc(100% - 0.5rem);
|
||||
height: 3px;
|
||||
background: rgb(108 117 125 / 76%);
|
||||
border-radius: 0.25rem 0.25rem 0 0;
|
||||
transform: translateY(0) translateZ(0);
|
||||
transition: transform 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active:after, .nav-tabs .nav-link:hover:after {
|
||||
transform: translateY(-3px) translateZ(0);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active:after {
|
||||
background: var(--primary);
|
||||
}
|
||||
|
||||
.nav-tabs li:first-child .nav-link {
|
||||
border-radius: 0.25rem 0 0 0;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
color: var(--primary);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.card-header-tabs {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tabs .nav-item.disabledTab a {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-item + .nav-item {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.datatable-footer .form-group {
|
||||
margin: 0;
|
||||
}
|
||||
.datatable-footer .col-form-label {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
border-bottom: none;
|
||||
padding-bottom: calc(0.5rem + 1px);
|
||||
box-shadow: 0px -1px 0px 0px #dee2e6 inset;
|
||||
}
|
||||
|
||||
.table {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.table th {
|
||||
color: var(--gray-dark);
|
||||
font-weight: 600;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.table td {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.table th[aria-sort]:hover {
|
||||
background: #dee2e6;
|
||||
}
|
||||
|
||||
.table th, .table td {
|
||||
padding: $paddingTable;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.table-striped tbody tr:nth-of-type(odd) {
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
.table-striped tbody tr:nth-of-type(even) {
|
||||
background: rgb(248 248 248);
|
||||
}
|
||||
|
||||
.table tbody tr:not(.b-table-details):not(.b-table-empty-row):not(.b-table-busy-slot):hover > td {
|
||||
background: rgb(0 123 255 / 10%);
|
||||
border-top: 1px solid var(--primary);
|
||||
border-bottom: 1px solid var(--primary);
|
||||
}
|
||||
|
||||
.table tbody tr:not(.b-table-details thead tr):not(.b-table-details):not(.b-table-empty-row):not(.b-table-busy-slot):hover {
|
||||
border: 1px solid var(--primary);
|
||||
}
|
||||
|
||||
.b-table-has-details td {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
$alergiaPrimary: #6f42c1;
|
||||
.btn-alergia { background-color: $alergiaPrimary !important; color: #FFFFFF !important; }
|
||||
.btn-alergia:hover { background-color: darken($alergiaPrimary, 5%) !important; }
|
||||
.btn-alergia:active { background-color: darken($alergiaPrimary, 10%) !important; }
|
||||
|
||||
$gestanteBase: #ffe6ff;
|
||||
$gestantePrimary: #e600e6;
|
||||
.gestante-base { background-color: $gestanteBase !important; }
|
||||
.gestante-background { background-color: $gestantePrimary !important; }
|
||||
.gestante-border { border-color: lighten($gestantePrimary, 45%) !important; }
|
||||
.gestante-color { color: $gestantePrimary !important; }
|
||||
.btn-gestante { background-color: $gestantePrimary !important; color: #FFFFFF !important; }
|
||||
.btn-gestante:hover { background-color: darken($gestantePrimary, 5%) !important; }
|
||||
.btn-gestante:active { background-color: darken($gestantePrimary, 10%) !important; }
|
||||
|
||||
|
||||
:root{
|
||||
--alergia-primary: #6f42c1;
|
||||
--gestante-primary: #e600e6;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
.pronto-atendimento-classificacao-risco-NAO_URGENTE{ color: #0000FF !important; }
|
||||
.pronto-atendimento-classificacao-risco-POUCO_URGENTE{ color: #008000 !important; }
|
||||
.pronto-atendimento-classificacao-risco-URGENTE{ color: #FFFF00 !important; }
|
||||
.pronto-atendimento-classificacao-risco-MUITO_URGENTE{ color: #FF7F00 !important; }
|
||||
.pronto-atendimento-classificacao-risco-EMERGENCIA{ color: #FF0000 !important; }
|
||||
@@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-form
|
||||
class="login-form"
|
||||
ref="form"
|
||||
v-if="isLayoutLogin"
|
||||
validate-on-submit
|
||||
@success="login"
|
||||
>
|
||||
<h1>Boas vindas ao <span>Conecta<strong>SU</strong></span></h1>
|
||||
<rkm-row class="justify-content-between">
|
||||
<template v-if="!$scopedSlots.mensagem">
|
||||
<rkm-col>
|
||||
<h5>Por favor informe seus dados</h5>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="auto">
|
||||
<h6>v{{ form.packageJSON.version }}</h6>
|
||||
</rkm-col>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<rkm-col>
|
||||
<slot name="mensagem"></slot>
|
||||
</rkm-col>
|
||||
</template>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:validations="validations.login.usuario"
|
||||
name="Usuário"
|
||||
v-model="model.login.usuario"
|
||||
>
|
||||
<rkm-input-group-prepend slot="prepend">
|
||||
<rkm-input-group-text><rkm-icon :icon="['far', 'user-circle']" /></rkm-input-group-text>
|
||||
</rkm-input-group-prepend>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:validations="validations.login.senha"
|
||||
name="Senha"
|
||||
:type="model.mostrarSenha ? 'text' : 'password'"
|
||||
v-model="model.login.senha"
|
||||
>
|
||||
<rkm-input-group-prepend slot="prepend">
|
||||
<rkm-input-group-text><rkm-icon icon="lock" /></rkm-input-group-text>
|
||||
</rkm-input-group-prepend>
|
||||
|
||||
<rkm-input-group-append slot="append">
|
||||
<rkm-input-group-text>
|
||||
<rkm-form-checkbox v-model="model.mostrarSenha">Mostrar senha</rkm-form-checkbox>
|
||||
</rkm-input-group-text>
|
||||
</rkm-input-group-append>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<div class="login-form-actions">
|
||||
<rkm-button
|
||||
color="primary"
|
||||
type="submit"
|
||||
>
|
||||
Realizar login
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button @click.stop="$router.push({ name: 'recuperar-senha', params: { customer: $route.params.customer } })">
|
||||
Esqueci minha senha
|
||||
</rkm-button>
|
||||
</div>
|
||||
</rkm-form>
|
||||
|
||||
<rkm-form
|
||||
v-else
|
||||
ref="form"
|
||||
class="login-form"
|
||||
>
|
||||
<h1>Alterar Senha</h1>
|
||||
|
||||
<rkm-row class="flex-nowrap justify-content-between">
|
||||
<rkm-col>
|
||||
<h5>Para continuar, defina uma nova senha para seu usuário.</h5>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row class="align-items-center">
|
||||
<rkm-col>
|
||||
|
||||
<rkm-form-input
|
||||
:validations="validations.trocaSenha.novaSenha"
|
||||
label="Nova Senha"
|
||||
type="password"
|
||||
v-model="model.trocaSenha.novaSenha"
|
||||
>
|
||||
<rkm-input-group-prepend slot="prepend">
|
||||
<rkm-input-group-text><rkm-icon icon="lock" /></rkm-input-group-text>
|
||||
</rkm-input-group-prepend>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:validations="validations.trocaSenha.novaSenhaConfirmation"
|
||||
label="Confirmar nova senha"
|
||||
type="password"
|
||||
v-model="model.trocaSenha.novaSenhaConfirmation"
|
||||
>
|
||||
<rkm-input-group-prepend slot="prepend">
|
||||
<rkm-input-group-text><rkm-icon icon="lock" /></rkm-input-group-text>
|
||||
</rkm-input-group-prepend>
|
||||
</rkm-form-input>
|
||||
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row class="justify-content-between">
|
||||
<rkm-col cols="auto" class="order-2">
|
||||
<rkm-button
|
||||
@click="$refs.form.validate(trocarSenha)"
|
||||
color="primary"
|
||||
>
|
||||
Continuar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="auto" class="order-1">
|
||||
<rkm-button
|
||||
@click="handleVoltarLogin()"
|
||||
>
|
||||
Voltar ao login
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import packageJSON from '/package.json'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import config from '@/config'
|
||||
import { repository, error, stringCase } from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.form.packageJSON = packageJSON
|
||||
this.repositories.cliente = this.getConectaSusRepository('intranet.cliente')
|
||||
this.repositories.autenticacao = this.getConectaSusRepository('administracao.autenticacao')
|
||||
},
|
||||
mixins: [ repository, error, stringCase ],
|
||||
data: () => ({
|
||||
form: {
|
||||
cliente: null,
|
||||
layout: 'login',
|
||||
packageJSON: null,
|
||||
},
|
||||
model: {
|
||||
login: {
|
||||
usuario: '',
|
||||
senha: ''
|
||||
},
|
||||
trocaSenha: {
|
||||
novaSenha: '',
|
||||
novaSenhaConfirmation: ''
|
||||
},
|
||||
mostrarSenha: false,
|
||||
},
|
||||
repositories: {},
|
||||
}),
|
||||
computed: {
|
||||
isLayoutLogin() {
|
||||
return this.form.layout == 'login'
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
login: {
|
||||
usuario: {
|
||||
required: true,
|
||||
min: 3
|
||||
},
|
||||
senha: {
|
||||
required: true,
|
||||
min: 8
|
||||
},
|
||||
},
|
||||
trocaSenha: {
|
||||
novaSenha: {
|
||||
required: true,
|
||||
senha: true
|
||||
},
|
||||
novaSenhaConfirmation: {
|
||||
required: true,
|
||||
is: this.model.trocaSenha.novaSenha
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapGetters({
|
||||
autenticacao: 'getAutenticacao'
|
||||
}),
|
||||
...mapActions([
|
||||
'clear',
|
||||
'setAutenticacao',
|
||||
'setCustomer',
|
||||
'setLoading',
|
||||
'unsetLoading',
|
||||
]),
|
||||
load(customer) {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.cliente.index({link: customer})
|
||||
.then(({ data }) => {
|
||||
this.setCustomer(data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleVoltarLogin() {
|
||||
this.model = {
|
||||
login: {
|
||||
usuario: '',
|
||||
senha: ''
|
||||
},
|
||||
trocaSenha: {
|
||||
novaSenha: '',
|
||||
novaSenhaConfirmation: ''
|
||||
},
|
||||
};
|
||||
this.form.layout = 'login'
|
||||
},
|
||||
login() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.autenticacao.login(this.model.login)
|
||||
.then(({ data }) => {
|
||||
|
||||
this.setAutenticacao(data)
|
||||
|
||||
this.unsetLoading()
|
||||
|
||||
if(data.usuario.trocaSenha) {
|
||||
this.form.layout = 'troca-senha'
|
||||
}else{
|
||||
this.$router.push({ name: 'lotacao' })
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
this.unsetLoading()
|
||||
this.handleError(error)
|
||||
})
|
||||
},
|
||||
trocarSenha() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.autenticacao.trocarSenha(
|
||||
this.autenticacao().usuario.id,
|
||||
this.camelObjectKeysToSnakeRecursive(this.model.trocaSenha)
|
||||
)
|
||||
.then(() => {
|
||||
|
||||
this.unsetLoading()
|
||||
|
||||
this.$router.push({ name: 'lotacao' })
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
this.unsetLoading()
|
||||
this.handleError(error)
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const env = config.ENV
|
||||
let customer = null
|
||||
|
||||
if (env === 'production') {
|
||||
customer = window.location.hostname.split('.')[0]
|
||||
} else {
|
||||
customer = this.$route.params.customer
|
||||
}
|
||||
|
||||
if(customer) {
|
||||
this.clear().then(() => {
|
||||
this.load(customer)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<rkm-form ref="form" class="login-form">
|
||||
<h1>Esqueceu sua senha?</h1>
|
||||
<h5>Informe seus dados para gerar uma nova</h5>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
name="CPF"
|
||||
v-model="model.cpf"
|
||||
v-mask="mask.cpf"
|
||||
:validations="validations.cpf"
|
||||
placeholder="CPF"
|
||||
>
|
||||
<rkm-input-group-prepend slot="prepend">
|
||||
<rkm-input-group-text><rkm-icon :icon="['far', 'user-circle']" /></rkm-input-group-text>
|
||||
</rkm-input-group-prepend>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
name="E-mail"
|
||||
placeholder="E-mail"
|
||||
v-model="model.email"
|
||||
:validations="validations.email"
|
||||
>
|
||||
<rkm-input-group-prepend slot="prepend">
|
||||
<rkm-input-group-text><rkm-icon :icon="['far', 'envelope']" /></rkm-input-group-text>
|
||||
</rkm-input-group-prepend>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<div class="login-form-actions">
|
||||
<rkm-button
|
||||
color="primary"
|
||||
type="submit"
|
||||
@click="$refs.form.validate(recuperarAcesso)"
|
||||
>
|
||||
Recuperar acesso
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click.stop="$router.push({ name: 'login', params: { customer: $route.params.customer } })"
|
||||
>
|
||||
Voltar ao login
|
||||
</rkm-button>
|
||||
</div>
|
||||
</rkm-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from "vuex"
|
||||
import config from '@/config'
|
||||
import { repository, error, mask, unmask } from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories.cliente = this.getConectaSusRepository('intranet.cliente')
|
||||
this.repositories.autenticacao = this.getConectaSusRepository('administracao.autenticacao')
|
||||
},
|
||||
mixins: [ repository, error, mask, unmask ],
|
||||
data: () => ({
|
||||
model: {
|
||||
cpf: null,
|
||||
email: null,
|
||||
},
|
||||
repositories: {},
|
||||
}),
|
||||
computed: {
|
||||
validations() {
|
||||
return {
|
||||
cpf: {
|
||||
required: true,
|
||||
min_max_without_mask: 11,
|
||||
cpf: true
|
||||
},
|
||||
email: {
|
||||
required: true,
|
||||
min: 5,
|
||||
max: 180,
|
||||
email: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
'setLoading',
|
||||
'unsetLoading',
|
||||
'setAutenticacao',
|
||||
'setCustomer',
|
||||
'clear'
|
||||
]),
|
||||
load(customer) {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.cliente.index({link: customer})
|
||||
.then(({ data }) => {
|
||||
this.setCustomer(data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
recuperarAcesso() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.autenticacao.recuperarSenha({
|
||||
cpf: this.unMaskCpf(this.model.cpf),
|
||||
email: this.model.email
|
||||
})
|
||||
.then(({ data }) => {
|
||||
|
||||
this.showSaveNotification(data.message)
|
||||
|
||||
this.$router.push({ name: 'login', params: { customer: this.$route.params.customer } })
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const env = config.ENV
|
||||
let customer = null
|
||||
|
||||
if (env === 'production') {
|
||||
customer = window.location.hostname.split('.')[0]
|
||||
} else {
|
||||
customer = this.$route.params.customer
|
||||
}
|
||||
|
||||
this.clear().then(() => {
|
||||
if(customer) {
|
||||
this.load(customer)
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
button:focus {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#recuperar-senha-inner {
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
#recuperar-senha-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#metodo-recuperacao label:before, #metodo-recuperacao label:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#metodo-recuperacao .custom-radio {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#metodo-recuperacao label {
|
||||
display: block;
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
padding: 2rem;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
background: #FFF;
|
||||
transition: border-color 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#metodo-recuperacao input:checked + label {
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0px 0px 0 3px rgb(63 106 216 / 30%), 0px 0px 30px -10px var(--primary);
|
||||
}
|
||||
|
||||
.list-group-item[selected] {
|
||||
background: rgb(63 106 216 / 5%);
|
||||
border-color: var(--primary);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#metodo-recuperacao label strong {
|
||||
display: block;
|
||||
font-size: 17px;
|
||||
}
|
||||
</style>
|
||||
81
frontend/src/components/administracao/configuracao/Form.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<rkm-form
|
||||
v-if="model"
|
||||
ref="RkmForm"
|
||||
>
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="BPA"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-select
|
||||
:options="form.instrumentosRegistro"
|
||||
label="Instrumento de registro padrão"
|
||||
text-field="nome"
|
||||
v-model="model.bpaIntrumentoRegistroPadrao"
|
||||
value-field="codigo"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-area>
|
||||
</rkm-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Vuex.
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
// Mixins.
|
||||
import { error, repository, stringCase } from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories = {
|
||||
configuracao: this.getConectaSusRepository('administracao.configuracao')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
form: null,
|
||||
model: null,
|
||||
cotaFormatoTrabalhoAtual: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.configuracao.edit()
|
||||
.then(response => {
|
||||
this.form = Object.assign(response.data.form)
|
||||
this.model = Object.assign(response.data.model)
|
||||
|
||||
this.cotaFormatoTrabalhoAtual = this.model.cotaFormatoTrabalho
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
save() {
|
||||
this.$refs.RkmForm.validate()
|
||||
.then(valid => {
|
||||
if (valid) {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.configuracao.update(this.camelObjectKeysToSnakeRecursive(this.model))
|
||||
.then(response => {
|
||||
this.showSaveNotification()
|
||||
this.$emit('save', response)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mixins: [ error, repository, stringCase ],
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
225
frontend/src/components/administracao/gestor/Form.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<rkm-form
|
||||
v-if="model"
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="12">
|
||||
<rkm-form-input-autocomplete
|
||||
:repository="repositories.usuario"
|
||||
:search-fields="fields"
|
||||
label="Usuário"
|
||||
text-field="cidadaoNome"
|
||||
v-model="model.usuario"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-area
|
||||
v-if="form.papeis.length > 0"
|
||||
no-margin-top
|
||||
title="Papéis"
|
||||
>
|
||||
<rkm-form-checkbox-group v-model="model.papeis">
|
||||
<rkm-form-checkbox
|
||||
v-for="papel in form.papeis"
|
||||
:key="papel.id"
|
||||
:value="papel.id"
|
||||
>
|
||||
{{papel.nome}}
|
||||
</rkm-form-checkbox>
|
||||
</rkm-form-checkbox-group>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-row v-if="form.modulos.length > 0">
|
||||
<rkm-col>
|
||||
<rkm-tabs>
|
||||
<rkm-tab
|
||||
v-for="modulo in form.modulos"
|
||||
:key="modulo.id"
|
||||
:title="modulo.nome"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="12">
|
||||
<rkm-button
|
||||
@click="checkAll(modulo.id)"
|
||||
color="primary"
|
||||
small
|
||||
>
|
||||
Marcar todos
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="uncheckAll(modulo.id)"
|
||||
outline
|
||||
small
|
||||
>
|
||||
Desmarcar todos
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row cols="3">
|
||||
<rkm-col
|
||||
v-for="funcionalidade in modulo.funcionalidades"
|
||||
:key="funcionalidade.id"
|
||||
>
|
||||
<rkm-area
|
||||
:title="funcionalidade.nome"
|
||||
no-margin-top
|
||||
>
|
||||
<rkm-form-checkbox-group v-model="model.permissoes">
|
||||
<rkm-form-checkbox
|
||||
v-for="permissao in funcionalidade.permissoes"
|
||||
:key="permissao.id"
|
||||
:value="permissao.id"
|
||||
>
|
||||
{{permissao.nome}}
|
||||
</rkm-form-checkbox>
|
||||
</rkm-form-checkbox-group>
|
||||
</rkm-area>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-tab>
|
||||
</rkm-tabs>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, object, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
validations() {
|
||||
return {
|
||||
nome: {
|
||||
required: true,
|
||||
min: 3,
|
||||
max: 100,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
gestor: this.getConectaSusRepository('administracao.gestor'),
|
||||
usuario: this.getConectaSusRepository('cadastro.sujeitoAtencao.usuario')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
fields: [
|
||||
{key: 'cadastro_cidadao.nome', searchable: true},
|
||||
],
|
||||
form: null,
|
||||
model: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
checkAll(moduloId) {
|
||||
const modulo = this.form.modulos.find(modulo => modulo.id === moduloId)
|
||||
|
||||
if (modulo) {
|
||||
modulo.funcionalidades.map(funcionalidade => funcionalidade.permissoes.map(permissao => {
|
||||
if (!this.model.permissoes.includes(permissao.id)) {
|
||||
this.model.permissoes.push(permissao.id)
|
||||
}
|
||||
}))
|
||||
}
|
||||
},
|
||||
uncheckAll(moduloId) {
|
||||
const modulo = this.form.modulos.find(modulo => modulo.id === moduloId)
|
||||
|
||||
if (modulo) {
|
||||
modulo.funcionalidades.map(funcionalidade => funcionalidade.permissoes.map(permissao => {
|
||||
const index = this.model.permissoes.findIndex(id => id === permissao.id)
|
||||
|
||||
if (index >= 0) {
|
||||
this.model.permissoes.splice(index, 1)
|
||||
}
|
||||
}))
|
||||
}
|
||||
},
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
const request = this.id
|
||||
? this.repositories.gestor.edit(this.id)
|
||||
: this.repositories.gestor.create()
|
||||
|
||||
request
|
||||
.then(({data}) => {
|
||||
this.form = data.form
|
||||
this.model = data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
store() {
|
||||
this.$refs.Form.validate()
|
||||
.then(valid => {
|
||||
if (!valid) return
|
||||
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
usuarioId: this.model.usuario ? this.model.usuario.id : null,
|
||||
permissoes: this.model.permissoes,
|
||||
papeis: this.model.papeis,
|
||||
}
|
||||
|
||||
this.repositories.gestor.store(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data }) => {
|
||||
this.showSaveNotification()
|
||||
this.$emit('save', data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
update() {
|
||||
this.$refs.Form.validate()
|
||||
.then(valid => {
|
||||
if (!valid) return
|
||||
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
usuarioId: this.model.usuario ? this.model.usuario.id : null,
|
||||
permissoes: this.model.permissoes,
|
||||
papeis: this.model.papeis,
|
||||
}
|
||||
|
||||
this.repositories.gestor.update(this.id, this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data }) => {
|
||||
this.showSaveNotification()
|
||||
this.$emit('save', data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
save() {
|
||||
if (this.id) {
|
||||
this.update()
|
||||
} else {
|
||||
this.store()
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [error, object, repository, stringCase],
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
props: {
|
||||
id: {type: Number},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
58
frontend/src/components/administracao/gestor/List.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<rkm-data-table
|
||||
:fields="fields"
|
||||
:repository="repositories.gestor"
|
||||
ref="DataTable"
|
||||
sort-by="nome"
|
||||
>
|
||||
<template v-slot:cell(actions)="{ item }">
|
||||
<rkm-button
|
||||
@click.stop="$router.push({name: 'administracao-gestor-edit', params: {id: item.id}})"
|
||||
authorize="update-administracao-gestor"
|
||||
color="primary"
|
||||
small
|
||||
title="Editar"
|
||||
>
|
||||
<rkm-icon icon="pen" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click.stop="handleDestroy(item)"
|
||||
authorize="destroy-administracao-gestor"
|
||||
color="danger"
|
||||
small
|
||||
title="Excluir"
|
||||
>
|
||||
<rkm-icon icon="trash" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-data-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {repository, error} from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories = {
|
||||
gestor: this.getConectaSusRepository('administracao.gestor')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
fields: [
|
||||
{key: 'nome', label: 'Nome', name: 'cadastroCidadao.nome', searchable: true, sortable: true},
|
||||
{class: 'col-min', key: 'actions', label: 'Ações', name: 'actions'},
|
||||
],
|
||||
}),
|
||||
methods: {
|
||||
handleDestroy({id}) {
|
||||
const destroy = () => this.repositories.gestor.destroy(id)
|
||||
.then(() => this.$refs.DataTable.refresh())
|
||||
|
||||
this.showDeleteConfirmation('Deseja realmente excluir o gestor?', destroy, this.handleError)
|
||||
},
|
||||
},
|
||||
mixins: [repository, error],
|
||||
}
|
||||
</script>
|
||||
213
frontend/src/components/administracao/notificacao/Form.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<rkm-form
|
||||
v-if="model"
|
||||
ref="RkmForm"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="4">
|
||||
<rkm-form-select
|
||||
:options="form.tipos"
|
||||
:validations="validations.tipo"
|
||||
label="Tipo"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.tipoId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="4">
|
||||
<rkm-form-multiselect
|
||||
:options="form.unidades"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleUnidadeClosed"
|
||||
label="Unidades"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="unidade selecionado"
|
||||
v-model="model.unidades"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="4">
|
||||
<rkm-form-multiselect
|
||||
:options="form.infraestruturas"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleInfraestruturaClosed"
|
||||
label="Local de atendimento"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="local selecionado"
|
||||
v-model="model.infraestruturas"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="4">
|
||||
<rkm-form-multiselect
|
||||
:options="form.usuarios"
|
||||
:select-limit="null"
|
||||
label="Usuários"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="usuário selecionado"
|
||||
v-model="model.usuarios"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="8">
|
||||
<rkm-form-input
|
||||
:validations="validations.titulo"
|
||||
label="Título"
|
||||
v-model="model.titulo"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="12">
|
||||
<rkm-text-editor
|
||||
:validations="validations.mensagem"
|
||||
label="Mensagem"
|
||||
v-model="model.mensagem"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, object, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
validations() {
|
||||
return {
|
||||
tipo: {required: true},
|
||||
titulo: {
|
||||
required: true,
|
||||
min: 3,
|
||||
max: 200,
|
||||
},
|
||||
mensagem: {
|
||||
required: true,
|
||||
min: 3,
|
||||
max: 5000,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
notificacao: this.getConectaSusRepository('administracao.notificacao')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
form: null,
|
||||
model: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
if (this.id) {
|
||||
this.repositories.notificacao.edit(this.id)
|
||||
.then(response => {
|
||||
this.form = Object.assign(response.data.form)
|
||||
this.model = Object.assign(response.data.model)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
|
||||
} else {
|
||||
this.repositories.notificacao.create()
|
||||
.then(response => {
|
||||
this.form = Object.assign(response.data.form)
|
||||
this.model = Object.assign(response.data.model)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
}
|
||||
},
|
||||
handleUnidadeClosed() {
|
||||
const request = {
|
||||
listar: 'infraestruturas',
|
||||
unidades: this.model.unidades,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.notificacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleInfraestruturaClosed() {
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.notificacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
save() {
|
||||
this.$refs.RkmForm.validate()
|
||||
.then(valid => {
|
||||
if (valid === false) return
|
||||
|
||||
const request = {
|
||||
tipoId: this.model.tipoId,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
usuarios: this.model.usuarios,
|
||||
titulo: this.model.titulo,
|
||||
mensagem: this.model.mensagem,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
if (this.model.id) {
|
||||
this.repositories.notificacao.update(this.model.id, this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.showSaveNotification()
|
||||
this.$emit('saved', response)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
} else {
|
||||
this.repositories.notificacao.store(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.showSaveNotification()
|
||||
this.$emit('saved', response)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mixins: [error, object, repository, stringCase],
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
props: {
|
||||
id: {type: Number},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
61
frontend/src/components/administracao/notificacao/List.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<rkm-data-table
|
||||
:fields="fields"
|
||||
:repository="repositories.notificacao"
|
||||
ref="DataTable"
|
||||
sort-by="dataHoraAtualizacao"
|
||||
:sort-desc="true"
|
||||
>
|
||||
<template v-slot:cell(actions)="{item}">
|
||||
<rkm-button
|
||||
@click.stop="$router.push({name: 'administracao-notificacao-edit', params: {id: item.id}})"
|
||||
authorize="update-administracao-notificacao"
|
||||
color="primary"
|
||||
small
|
||||
title="Editar"
|
||||
>
|
||||
<rkm-icon icon="pen" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click.stop="destroy(item)"
|
||||
authorize="destroy-administracao-notificacao"
|
||||
color="danger"
|
||||
small
|
||||
title="Excluir"
|
||||
>
|
||||
<rkm-icon icon="trash" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-data-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, repository} from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories = {
|
||||
notificacao: this.getConectaSusRepository('administracao.notificacao')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
fields: [
|
||||
{key: 'dataHoraAtualizacao', label: 'Data/Hora', searchable: true, sortable: true},
|
||||
{key: 'tipoNome', label: 'Tipo', name: 'administracao_notificacao_tipo.nome', searchable: true, sortable: true},
|
||||
{key: 'titulo', label: 'Título', name: 'administracao_notificacao.titulo', searchable: true, sortable: true},
|
||||
{class: 'col-min text-center', key: 'actions', label: 'Ações'},
|
||||
],
|
||||
}),
|
||||
methods: {
|
||||
destroy({ id }) {
|
||||
const destroy = () => this.repositories.notificacao.destroy(id)
|
||||
.then(() => this.$refs.DataTable.refresh())
|
||||
|
||||
this.showDeleteConfirmation('Deseja realmente excluir a notificação?', destroy, this.handleError)
|
||||
},
|
||||
},
|
||||
mixins: [error, repository],
|
||||
}
|
||||
</script>
|
||||
135
frontend/src/components/administracao/notificacao/Modal.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-modal
|
||||
extra-large
|
||||
ref="RkmModal"
|
||||
title="Notificações"
|
||||
>
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="items"
|
||||
sort-by="dataHoraAtualizacao"
|
||||
:sort-desc="true"
|
||||
:sort-compare="sortCompare"
|
||||
@sort-changed="handleSortChange"
|
||||
>
|
||||
<template v-slot:cell(actions)="{item}">
|
||||
<rkm-button
|
||||
@click="$refs.ModalMensagem.open(item)"
|
||||
color="primary"
|
||||
small
|
||||
title="Mensagem"
|
||||
>
|
||||
<rkm-icon icon="search" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-table>
|
||||
|
||||
<template v-slot:footer="{cancel}">
|
||||
<rkm-button
|
||||
:disabled="!!loading"
|
||||
@click="cancel"
|
||||
color="secondary"
|
||||
>
|
||||
Fechar
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-modal>
|
||||
|
||||
<ModalMensagem ref="ModalMensagem" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import ModalMensagem from './components/mensagem/Modal'
|
||||
|
||||
// Mixins.
|
||||
import {error, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions, mapGetters} from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {ModalMensagem},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
loading: 'getLoading',
|
||||
lotacao: 'getLotacao',
|
||||
}),
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
notificacao: this.getConectaSusRepository('administracao.notificacao'),
|
||||
}
|
||||
if (!this.model) {
|
||||
this.model = {
|
||||
sortBy: 'dataHoraAtualizacao',
|
||||
sortDesc: true
|
||||
};
|
||||
} else {
|
||||
this.model.sortBy = this.sortBy || 'dataHoraAtualizacao';
|
||||
this.model.sortDesc = this.sortDesc !== undefined ? this.sortDesc : true;
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
fields: [
|
||||
{key: 'dataHoraAtualizacao',
|
||||
label: 'Data/Hora',
|
||||
searchable: true,
|
||||
sortable: true,
|
||||
sortDirection: 'desc'
|
||||
},
|
||||
{key: 'tipoNome', label: 'Tipo', sortable: true},
|
||||
{key: 'titulo', label: 'Título', sortable: true},
|
||||
{filterByFormatted: true, formatter: (value) => value ? 'Sim' : 'Não' , key: 'visualizado', label: 'Visualizada', sortable: true},
|
||||
{class: 'col-min text-center', key: 'actions', label: 'Ações'},
|
||||
],
|
||||
items: [],
|
||||
order: {
|
||||
by: 'dataHoraAtualizacao',
|
||||
dir: 'desc'
|
||||
},
|
||||
model: {
|
||||
sortBy: 'dataHoraAtualizacao',
|
||||
sortDesc: true
|
||||
}
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
open() {
|
||||
this.load()
|
||||
this.$refs.RkmModal.show()
|
||||
},
|
||||
load() {
|
||||
const request = {
|
||||
lotacaoId: this.lotacao.id,
|
||||
order: this.order
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.notificacao.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.items = Object.assign(response.data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleSortChange(ctx) {
|
||||
if (ctx) {
|
||||
this.order.by = ctx.sortby
|
||||
this.order.dir = ctx.sortDesc ? 'desc' : 'asc'
|
||||
}
|
||||
this.load()
|
||||
},
|
||||
sortCompare(a, b, key) {
|
||||
if (key === 'dataHoraAtualizacao') {
|
||||
return new Date(a[key]) - new Date(b[key]);
|
||||
}
|
||||
return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0;
|
||||
}
|
||||
},
|
||||
mixins: [error, repository, stringCase],
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<rkm-modal
|
||||
:title="title"
|
||||
@hide="hide"
|
||||
extra-large
|
||||
ref="RkmModal"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="12">
|
||||
<span v-html="item ? item.mensagem : null" />
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<template v-slot:footer="{cancel}">
|
||||
<rkm-button
|
||||
@click="cancel"
|
||||
color="secondary"
|
||||
>
|
||||
Fechar
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions, mapGetters} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({quantidadeNotificacoesNaoLidas: 'getQuantidadeNotificacoesNaoLidas'}),
|
||||
title() {
|
||||
return this.item ? `${this.item.tipoNome} - ${this.item.titulo}` : null
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
notificacao: this.getConectaSusRepository('administracao.notificacao'),
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
item: null,
|
||||
}),
|
||||
methods: {
|
||||
...mapActions([
|
||||
'setLoading',
|
||||
'setQuantidadeNotificacoesNaoLidas',
|
||||
'unsetLoading',
|
||||
]),
|
||||
open(item) {
|
||||
this.item = item
|
||||
this.$refs.RkmModal.show()
|
||||
},
|
||||
hide() {
|
||||
if (this.item.visualizado) return
|
||||
|
||||
const request = {
|
||||
lotacaoId: this.item.lotacaoId,
|
||||
visualizado: true,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.notificacao.patch(this.item.id, this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(() => {
|
||||
this.item.visualizado = true
|
||||
this.setQuantidadeNotificacoesNaoLidas(this.quantidadeNotificacoesNaoLidas - 1)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
mixins: [error, repository, stringCase],
|
||||
}
|
||||
</script>
|
||||
184
frontend/src/components/administracao/papel/Form.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
label="Nome"
|
||||
v-model="model.nome"
|
||||
:validations="validations.nome"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row v-if="form.modulos.length > 0">
|
||||
<rkm-col>
|
||||
<rkm-tabs>
|
||||
<rkm-tab
|
||||
v-for="modulo in form.modulos"
|
||||
:key="modulo.id"
|
||||
:title="modulo.nome"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-button
|
||||
@click="checkAll(modulo.id)"
|
||||
color="primary"
|
||||
small
|
||||
>
|
||||
Marcar todos
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="uncheckAll(modulo.id)"
|
||||
outline
|
||||
small
|
||||
>
|
||||
Desmarcar todos
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row cols="3">
|
||||
<rkm-col
|
||||
v-for="funcionalidade in modulo.funcionalidades"
|
||||
:key="funcionalidade.id"
|
||||
>
|
||||
<rkm-area
|
||||
:title="funcionalidade.nome"
|
||||
no-margin-top
|
||||
>
|
||||
<rkm-form-checkbox-group v-model="model.permissoes">
|
||||
<rkm-form-checkbox
|
||||
v-for="permissao in funcionalidade.permissoes"
|
||||
:key="permissao.id"
|
||||
:value="permissao.id"
|
||||
>
|
||||
{{ permissao.nome }}
|
||||
</rkm-form-checkbox>
|
||||
</rkm-form-checkbox-group>
|
||||
</rkm-area>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-tab>
|
||||
</rkm-tabs>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Vuex.
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
// Mixins.
|
||||
import { repository, stringCase, object, error } from '@/mixins'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
validations() {
|
||||
|
||||
return {
|
||||
nome: {
|
||||
required: true,
|
||||
min: 3,
|
||||
max: 100,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
papel: this.getConectaSusRepository('administracao.papel')
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data: () => ({
|
||||
form: {
|
||||
modulos: []
|
||||
},
|
||||
model: {
|
||||
permissoes: []
|
||||
},
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
checkAll(moduloId) {
|
||||
|
||||
this.form.modulos.find(m => m.id === moduloId).funcionalidades
|
||||
.map(f => f.permissoes.map(permissao => {
|
||||
|
||||
if (!this.model.permissoes.includes(permissao.id)) {
|
||||
|
||||
this.model.permissoes.push(permissao.id)
|
||||
}
|
||||
}))
|
||||
},
|
||||
uncheckAll(moduloId) {
|
||||
|
||||
this.form.modulos.find(m => m.id === moduloId).funcionalidades
|
||||
.map(f => f.permissoes.map(permissao => {
|
||||
|
||||
const index = this.model.permissoes.findIndex(id => id === permissao.id)
|
||||
|
||||
if (index >= 0) {
|
||||
|
||||
this.model.permissoes.splice(index, 1)
|
||||
}
|
||||
}))
|
||||
},
|
||||
load() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
const request = this.id
|
||||
? this.repositories.papel.edit(this.id)
|
||||
: this.repositories.papel.create()
|
||||
|
||||
request
|
||||
.then(({ data }) => {
|
||||
|
||||
this.form = data.form
|
||||
this.model = data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
save() {
|
||||
|
||||
this.$refs.Form.validate()
|
||||
.then(valid => {
|
||||
|
||||
if (!valid) return
|
||||
|
||||
this.setLoading()
|
||||
|
||||
const request = this.id
|
||||
? this.repositories.papel.update(this.id, this.prepareData())
|
||||
: this.repositories.papel.store(this.prepareData())
|
||||
|
||||
request
|
||||
.then(({ data }) => {
|
||||
|
||||
this.showSaveNotification()
|
||||
this.$emit('save', data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
prepareData() {
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(this.clone(this.model))
|
||||
},
|
||||
},
|
||||
mixins: [repository, stringCase, object, error],
|
||||
props: {
|
||||
id: { type: Number }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
71
frontend/src/components/administracao/papel/List.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<rkm-data-table
|
||||
:fields="fields"
|
||||
:repository="repositories.papel"
|
||||
ref="DataTable"
|
||||
sort-by="nome"
|
||||
>
|
||||
<template v-slot:cell(actions)="{ item }">
|
||||
<rkm-button
|
||||
@click.stop="$router.push({ name: 'administracao-papel-edit', params: { id: item.id } })"
|
||||
color="primary"
|
||||
authorize="update-administracao-papel"
|
||||
title="Editar"
|
||||
small
|
||||
>
|
||||
<rkm-icon icon="pen" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click.stop="handleDestroy(item)"
|
||||
color="danger"
|
||||
authorize="destroy-administracao-papel"
|
||||
title="Excluir"
|
||||
small
|
||||
>
|
||||
<rkm-icon icon="trash" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-data-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import { repository, error } from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
papel: this.getConectaSusRepository('administracao.papel')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
fields: [
|
||||
{
|
||||
name: 'papel.nome',
|
||||
key: 'nome',
|
||||
label: 'Nome',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
key: 'actions',
|
||||
label: 'Ações',
|
||||
class: 'col-min'
|
||||
},
|
||||
],
|
||||
}),
|
||||
methods: {
|
||||
handleDestroy({ id }) {
|
||||
|
||||
const destroy = () => this.repositories.papel.destroy(id)
|
||||
.then(() => this.$refs.DataTable.refresh())
|
||||
|
||||
this.showDeleteConfirmation('Deseja realmente excluir o papel?', destroy, this.handleError)
|
||||
},
|
||||
},
|
||||
mixins: [repository, error],
|
||||
}
|
||||
</script>
|
||||
211
frontend/src/components/administracao/permissao/Form.vue
Normal file
@@ -0,0 +1,211 @@
|
||||
<template>
|
||||
<rkm-form ref="Form">
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input
|
||||
disabled
|
||||
label="Unidade"
|
||||
v-model="form.unidadeNomeFantasia"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input
|
||||
disabled
|
||||
label="Local de atendimento"
|
||||
v-model="form.infraestruturaNome"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input
|
||||
disabled
|
||||
label="Usuário"
|
||||
v-model="form.usuarioNome"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input
|
||||
disabled
|
||||
label="CBO"
|
||||
v-model="form.ocupacaoNome"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-area
|
||||
v-if="form.papeis.length > 0"
|
||||
no-margin-top
|
||||
title="Papéis"
|
||||
>
|
||||
<rkm-form-checkbox-group v-model="model.papeis">
|
||||
<rkm-form-checkbox
|
||||
v-for="papel in form.papeis"
|
||||
:key="papel.id"
|
||||
:value="papel.id"
|
||||
>
|
||||
{{ papel.nome }}
|
||||
</rkm-form-checkbox>
|
||||
</rkm-form-checkbox-group>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-area
|
||||
v-if="form.modulos.length > 0"
|
||||
no-margin-top
|
||||
title="Permissões"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-tabs>
|
||||
<rkm-tab
|
||||
v-for="modulo in form.modulos"
|
||||
:key="modulo.id"
|
||||
:title="modulo.nome"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-button
|
||||
@click="checkAll(modulo.id)"
|
||||
color="primary"
|
||||
small
|
||||
>
|
||||
Marcar todos
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="uncheckAll(modulo.id)"
|
||||
outline
|
||||
small
|
||||
>
|
||||
Desmarcar todos
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row cols="3">
|
||||
<rkm-col
|
||||
v-for="funcionalidade in modulo.funcionalidades"
|
||||
:key="funcionalidade.id"
|
||||
>
|
||||
<rkm-area
|
||||
:title="funcionalidade.nome"
|
||||
no-margin-top
|
||||
>
|
||||
<rkm-form-checkbox-group v-model="model.permissoes">
|
||||
<rkm-form-checkbox
|
||||
v-for="permissao in funcionalidade.permissoes"
|
||||
:key="permissao.id"
|
||||
:value="permissao.id"
|
||||
>
|
||||
{{ permissao.nome }}
|
||||
</rkm-form-checkbox>
|
||||
</rkm-form-checkbox-group>
|
||||
</rkm-area>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-tab>
|
||||
</rkm-tabs>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-area>
|
||||
</rkm-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Vuex.
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
// Mixins.
|
||||
import { repository, stringCase, object, error } from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
permissao: this.getConectaSusRepository('administracao.permissao')
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data: () => ({
|
||||
form: {
|
||||
papeis: [],
|
||||
modulos: []
|
||||
},
|
||||
model: {
|
||||
papeis: [],
|
||||
permissoes: []
|
||||
},
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
checkAll(moduloId) {
|
||||
|
||||
this.form.modulos.find(m => m.id === moduloId).funcionalidades
|
||||
.map(f => f.permissoes.map(permissao => {
|
||||
|
||||
if (!this.model.permissoes.includes(permissao.id)) {
|
||||
|
||||
this.model.permissoes.push(permissao.id)
|
||||
}
|
||||
}))
|
||||
},
|
||||
uncheckAll(moduloId) {
|
||||
|
||||
this.form.modulos.find(m => m.id === moduloId).funcionalidades
|
||||
.map(f => f.permissoes.map(permissao => {
|
||||
|
||||
const index = this.model.permissoes.findIndex(id => id === permissao.id)
|
||||
|
||||
if (index >= 0) {
|
||||
|
||||
this.model.permissoes.splice(index, 1)
|
||||
}
|
||||
}))
|
||||
},
|
||||
load() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.permissao.edit(this.id)
|
||||
.then(({ data }) => {
|
||||
|
||||
this.form = data.form
|
||||
this.model = data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
save() {
|
||||
|
||||
this.$refs.Form.validate()
|
||||
.then(valid => {
|
||||
|
||||
if (!valid) return
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.permissao.update(this.id, this.prepareData())
|
||||
.then(({ data }) => {
|
||||
|
||||
this.showSaveNotification()
|
||||
this.$emit('save', data)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
prepareData() {
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(this.clone(this.model))
|
||||
},
|
||||
},
|
||||
mixins: [repository, stringCase, object, error],
|
||||
props: {
|
||||
id: { type: Number, required: true }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
73
frontend/src/components/administracao/permissao/List.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<rkm-data-table
|
||||
:fields="fields"
|
||||
:repository="repositories.permissao"
|
||||
ref="DataTable"
|
||||
sort-by="unidadeNomeFantasia"
|
||||
>
|
||||
<template v-slot:cell(actions)="{ item }">
|
||||
<rkm-button
|
||||
@click.stop="$router.push({ name: 'administracao-permissao-edit', params: { id: item.id } })"
|
||||
color="primary"
|
||||
authorize="update-administracao-permissao"
|
||||
title="Alterar permissões"
|
||||
small
|
||||
>
|
||||
<rkm-icon icon="key" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-data-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import { repository } from '@/mixins'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
permissao: this.getConectaSusRepository('administracao.permissao')
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
fields: [
|
||||
{
|
||||
name: 'unidade.nomeFantasia',
|
||||
key: 'unidadeNomeFantasia',
|
||||
label: 'Unidade',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'infraestrutura.nome',
|
||||
key: 'infraestruturaNome',
|
||||
label: 'Local de atendimento',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'cidadao.nome',
|
||||
key: 'usuarioNome',
|
||||
label: 'Usuário',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'ocupacao.nome',
|
||||
key: 'ocupacaoNome',
|
||||
label: 'CBO',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
key: 'actions',
|
||||
label: 'Ações',
|
||||
class: 'col-min'
|
||||
},
|
||||
],
|
||||
}),
|
||||
mixins: [repository],
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,620 @@
|
||||
<template>
|
||||
<div v-if="model">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-date-picker
|
||||
:end-validations="validations.data"
|
||||
:max-date="additionals.dataAtual"
|
||||
:range-inline="false"
|
||||
:start-validations="validations.data"
|
||||
end-label="Até"
|
||||
range
|
||||
start-label="Data de"
|
||||
v-model="model.data"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-time-picker
|
||||
:disabled="!model.data.start && !model.data.end"
|
||||
:validations="validations.hora.start"
|
||||
@input="handleHoraStartInput"
|
||||
label="Hora de"
|
||||
v-model="model.hora.start"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-time-picker
|
||||
:disabled="!model.data.start && !model.data.end"
|
||||
:validations="validations.hora.end"
|
||||
@input="handleHoraEndInput"
|
||||
label="Até"
|
||||
v-model="model.hora.end"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.usuarios"
|
||||
@change="handleUsuarioChange"
|
||||
default-option-text="Todos"
|
||||
label="Usuário"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.usuarioId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.unidades"
|
||||
@change="handleUnidadeChange"
|
||||
default-option-text="Todas"
|
||||
label="Unidade"
|
||||
show-default-option
|
||||
text-field="nomeFantasia"
|
||||
v-model="model.unidadeId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.infraestruturas"
|
||||
@change="handleInfraestruturaChange"
|
||||
default-option-text="Todos"
|
||||
label="Local de atendimento"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.infraestruturaId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.modulos"
|
||||
@change="handleModuloChange"
|
||||
default-option-text="Todos"
|
||||
label="Módulo"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.moduloId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.funcionalidades"
|
||||
@change="handleFuncionalidadeChange"
|
||||
default-option-text="Todas"
|
||||
label="Funcionalidade"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.funcionalidadeId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="2">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="$refs.Form.validate(search)"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="reset"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<template v-if="data">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-button
|
||||
@click="print"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="exportTo"
|
||||
color="info"
|
||||
small
|
||||
title="Exportar"
|
||||
>
|
||||
<rkm-icon icon="file-export" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="data.itens"
|
||||
:sort-by="sortBy"
|
||||
:sort-desc="sortDesc"
|
||||
@sort-changed="onSortChanged"
|
||||
hide-filters
|
||||
>
|
||||
<template v-slot:custom-foot>
|
||||
<rkm-tr>
|
||||
<rkm-th
|
||||
class="text-right"
|
||||
colspan="7"
|
||||
>
|
||||
Total: {{data.totalizadores.totalAcessos}}
|
||||
</rkm-th>
|
||||
</rkm-tr>
|
||||
</template>
|
||||
</rkm-table>
|
||||
</rkm-area>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, file, formats, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
validations() {
|
||||
return {
|
||||
data: {required: true},
|
||||
hora: {
|
||||
start: {
|
||||
max_hour: this.model.hora.end ? this.formatTime(this.model.hora.end) : null,
|
||||
},
|
||||
end: {
|
||||
min_hour: this.model.hora.start ? this.formatTime(this.model.hora.start) : null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
exportacao: this.getConectaSusRepository('exportacao.administracao'),
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioAcessoFuncionalidade: this.getConectaSusRepository('administracao.relatorioAcessoFuncionalidade'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
additionals: null,
|
||||
form: null,
|
||||
data: null,
|
||||
fields: [
|
||||
{key: 'data', label: 'Data', sortable: true},
|
||||
{key: 'hora', label: 'Hora', sortable: true},
|
||||
{key: 'usuarioNome', label: 'Usuário', sortable: true},
|
||||
{key: 'unidadeNomeFantasia', label: 'Unidade', sortable: true},
|
||||
{key: 'infraestruturaNome', label: 'Local de atendimento', sortable: true},
|
||||
{key: 'moduloNome', label: 'Módulo', sortable: true},
|
||||
{key: 'funcionalidadeNome', label: 'Funcionalidade', sortable: true},
|
||||
],
|
||||
model: null,
|
||||
others: {moment},
|
||||
sortBy: 'data',
|
||||
sortDesc: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.create()
|
||||
.then((response) => {
|
||||
this.additionals = response.data.additionals
|
||||
this.form = response.data.form
|
||||
this.model = response.data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
search() {
|
||||
const request = {
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
unidadeId: this.model.unidadeId,
|
||||
infraestruturaId: this.model.infraestruturaId,
|
||||
moduloId: this.model.moduloId,
|
||||
funcionalidadeId: this.model.funcionalidadeId,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.data = Object.assign(response.data))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
reset() {
|
||||
this.form.usuarios = []
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
|
||||
this.model.data = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.hora = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.usuarioId = null
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
this.$nextTick().then(() => this.$refs.Form.resetValidator())
|
||||
},
|
||||
print() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
unidadeId: this.model.unidadeId,
|
||||
infraestruturaId: this.model.infraestruturaId,
|
||||
moduloId: this.model.moduloId,
|
||||
funcionalidadeId: this.model.funcionalidadeId,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioAcessoFuncionalidade(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
exportTo() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
unidadeId: this.model.unidadeId,
|
||||
infraestruturaId: this.model.infraestruturaId,
|
||||
moduloId: this.model.moduloId,
|
||||
funcionalidadeId: this.model.funcionalidadeId,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.exportacao.relatorioAcessoFuncionalidade(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleHoraStartInput(value) {
|
||||
this.form.usuarios = []
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.model.usuarioId = null
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: value,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
this.form.unidades = Object.assign(response.data.unidades)
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleHoraEndInput(value) {
|
||||
this.form.usuarios = []
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.model.usuarioId = null
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: value,
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
this.form.unidades = Object.assign(response.data.unidades)
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUsuarioChange(value) {
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'unidades',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: value,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.unidades = Object.assign(response.data.unidades)
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUnidadeChange(value) {
|
||||
this.form.infraestruturas = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.model.infraestruturaId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'infraestruturas',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
unidadeId: value,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleInfraestruturaChange(value) {
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'modulos',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
unidadeId: this.model.unidadeId,
|
||||
infraestruturaId: value,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleModuloChange() {
|
||||
this.form.funcionalidades = []
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'funcionalidades',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
unidadeId: this.model.unidadeId,
|
||||
infraestruturaId: this.model.infraestruturaId,
|
||||
moduloId: this.model.moduloId,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.form.funcionalidades = Object.assign(response.data.funcionalidades))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleFuncionalidadeChange() {
|
||||
this.data = null
|
||||
},
|
||||
onSortChanged(context) {
|
||||
this.sortBy = context.sortBy
|
||||
this.sortDesc = context.sortDesc
|
||||
},
|
||||
},
|
||||
mixins: [error, file, formats, repository, stringCase],
|
||||
watch: {
|
||||
'model.data': {
|
||||
deep: true,
|
||||
handler(value) {
|
||||
this.form.usuarios = []
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
|
||||
this.model.hora = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.usuarioId = null
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.data = null
|
||||
|
||||
if (value.start === null || value.end === null) {
|
||||
return
|
||||
}
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoFuncionalidade.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
this.form.unidades = Object.assign(response.data.unidades)
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,464 @@
|
||||
<template>
|
||||
<div v-if="model">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-date-picker
|
||||
:end-validations="validations.data"
|
||||
:max-date="additionals.dataAtual"
|
||||
:range-inline="false"
|
||||
:start-validations="validations.data"
|
||||
end-label="Até"
|
||||
range
|
||||
start-label="Data de"
|
||||
v-model="model.data"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-time-picker
|
||||
:disabled="!model.data.start && !model.data.end"
|
||||
:validations="validations.hora.start"
|
||||
@input="handleHoraStartInput"
|
||||
label="Hora de"
|
||||
v-model="model.hora.start"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-time-picker
|
||||
:disabled="!model.data.start && !model.data.end"
|
||||
:validations="validations.hora.end"
|
||||
@input="handleHoraEndInput"
|
||||
label="Até"
|
||||
v-model="model.hora.end"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.usuarios"
|
||||
@change="handleUsuarioChange"
|
||||
default-option-text="Todos"
|
||||
label="Usuário"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.usuarioId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.status"
|
||||
@change="handleStatusChange"
|
||||
default-option-text="Todos"
|
||||
label="Status"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.statusId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="2">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="$refs.Form.validate(search)"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="reset"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<template v-if="data">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-button
|
||||
@click="print"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="exportTo"
|
||||
color="info"
|
||||
small
|
||||
title="Exportar"
|
||||
>
|
||||
<rkm-icon icon="file-export" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="data.itens"
|
||||
:sort-by="sortBy"
|
||||
:sort-desc="sortDesc"
|
||||
@sort-changed="onSortChanged"
|
||||
hide-filters
|
||||
/>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Totais"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:value="data.totalizadores.totalAcessos"
|
||||
disabled
|
||||
label="Total de acessos"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:value="data.totalizadores.totalAcessoRealizadoComSucesso"
|
||||
disabled
|
||||
label="Total de acessos realizados com sucesso"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:value="data.totalizadores.totalUsuarioEOuSenhaIncorretos"
|
||||
disabled
|
||||
label="Total de usuário e/ou senha incorretos"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:value="data.totalizadores.totalUsuarioBloqueado"
|
||||
disabled
|
||||
label="Total de usuários bloqueados"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:value="data.totalizadores.totalUsuarioAcesso"
|
||||
disabled
|
||||
label="Total de usuários que acessaram o sistema"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-area>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, file, formats, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
validations() {
|
||||
return {
|
||||
data: {required: true},
|
||||
hora: {
|
||||
start: {
|
||||
max_hour: this.model.hora.end ? this.formatTime(this.model.hora.end) : null,
|
||||
},
|
||||
end: {
|
||||
min_hour: this.model.hora.start ? this.formatTime(this.model.hora.start) : null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
exportacao: this.getConectaSusRepository('exportacao.administracao'),
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioAcessoSistema: this.getConectaSusRepository('administracao.relatorioAcessoSistema'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
additionals: null,
|
||||
form: null,
|
||||
data: null,
|
||||
fields: [
|
||||
{formatter: value => this.formatDate(value), key: 'data', label: 'Data', sortable: true},
|
||||
{key: 'hora', label: 'Hora', sortable: true},
|
||||
{key: 'usuarioNome', label: 'Usuário', sortable: true},
|
||||
{key: 'statusNome', label: 'Status', sortable: true},
|
||||
],
|
||||
model: null,
|
||||
others: {moment},
|
||||
sortBy: 'data',
|
||||
sortDesc: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoSistema.create()
|
||||
.then((response) => {
|
||||
this.additionals = response.data.additionals
|
||||
this.form = response.data.form
|
||||
this.model = response.data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
search() {
|
||||
const request = {
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
statusId: this.model.statusId,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoSistema.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.data = Object.assign(response.data))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
reset() {
|
||||
this.form.usuarios = []
|
||||
this.form.status = []
|
||||
|
||||
this.model.data = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.hora = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.usuarioId = null
|
||||
this.model.statusId = null
|
||||
this.data = null
|
||||
|
||||
this.$nextTick().then(() => this.$refs.Form.resetValidator())
|
||||
},
|
||||
print() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
statusId: this.model.statusId,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioAcessoSistema(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
exportTo() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
usuarioId: this.model.usuarioId,
|
||||
statusId: this.model.statusId,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.exportacao.relatorioAcessoSistema(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleHoraStartInput(value) {
|
||||
this.form.usuarios = []
|
||||
this.form.status = []
|
||||
this.model.usuarioId = null
|
||||
this.model.statusId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: value,
|
||||
end: this.model.hora.end,
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoSistema.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
this.form.status = Object.assign(response.data.status)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleHoraEndInput(value) {
|
||||
this.form.usuarios = []
|
||||
this.form.status = []
|
||||
this.model.usuarioId = null
|
||||
this.model.statusId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: value,
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoSistema.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
this.form.status = Object.assign(response.data.status)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUsuarioChange(value) {
|
||||
this.form.status = []
|
||||
this.model.statusId = null
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'status',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
hora: {
|
||||
start: this.model.hora.start,
|
||||
end: this.model.hora.end,
|
||||
usuarioId: value,
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoSistema.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.form.status = Object.assign(response.data.status))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleStatusChange() {
|
||||
this.data = null
|
||||
},
|
||||
onSortChanged(context) {
|
||||
this.sortBy = context.sortBy
|
||||
this.sortDesc = context.sortDesc
|
||||
},
|
||||
},
|
||||
mixins: [error, file, formats, repository, stringCase],
|
||||
watch: {
|
||||
'model.data': {
|
||||
deep: true,
|
||||
handler(value) {
|
||||
this.form.usuarios = []
|
||||
this.form.status = []
|
||||
|
||||
this.model.hora = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.usuarioId = null
|
||||
this.model.statusId = null
|
||||
this.data = null
|
||||
|
||||
if (value.start === null || value.end === null) {
|
||||
return
|
||||
}
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
data: {
|
||||
start: this.others.moment(this.model.data.start).format('DD/MM/YYYY'),
|
||||
end: this.others.moment(this.model.data.end).format('DD/MM/YYYY'),
|
||||
},
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioAcessoSistema.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = Object.assign(response.data.usuarios)
|
||||
this.form.status = Object.assign(response.data.status)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,631 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
v-if="model"
|
||||
ref="RkmForm"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-date-picker
|
||||
:end-validations="validations.periodo"
|
||||
:max-date="additionals.dataAtual"
|
||||
:range-inline="false"
|
||||
:start-validations="validations.periodo"
|
||||
end-label="Até"
|
||||
range
|
||||
start-label="Período de"
|
||||
v-model="model.periodo"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.unidades"
|
||||
@change="handleUnidadeChange"
|
||||
default-option-text="Todas"
|
||||
label="Unidade"
|
||||
show-default-option
|
||||
text-field="nomeFantasia"
|
||||
v-model="model.unidadeId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.infraestruturas"
|
||||
@change="handleInfraestruturaChange"
|
||||
default-option-text="Todos"
|
||||
label="Local de atendimento"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.infraestruturaId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.lotacoes"
|
||||
@change="handleLotacaoChange"
|
||||
default-option-text="Todos"
|
||||
label="CBO"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.ocupacaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.papeis"
|
||||
@change="handlePapelChange"
|
||||
default-option-text="Todos"
|
||||
label="Papel"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.papelId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.acoes"
|
||||
@change="handleAcaoChange"
|
||||
default-option-text="Todas"
|
||||
label="Tipo de ação"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.acaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input-autocomplete
|
||||
:disabled="!model.periodo.start || !model.periodo.end"
|
||||
:repository="repositories.relatorioHistoricoPapelLotacao.usuario"
|
||||
:request-query-string-params="requestQueryStringParamsUsuario"
|
||||
:search-fields="[{ key: 'cadastro_cidadao.nome', searchable: true }]"
|
||||
label="Usuário"
|
||||
v-model="model.usuario"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input-autocomplete
|
||||
:disabled="!model.periodo.start || !model.periodo.end"
|
||||
:repository="repositories.relatorioHistoricoPapelLotacao.usuarioResponsavel"
|
||||
:request-query-string-params="requestQueryStringParamsUsuarioResponsavel"
|
||||
:search-fields="[{ key: 'cadastro_cidadao.nome', searchable: true }]"
|
||||
label="Permitido por"
|
||||
v-model="model.usuarioResponsavel"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="handleBuscarClick"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="handleLimparClick"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-dropdown
|
||||
class="mr-2"
|
||||
color="primary"
|
||||
cols="1"
|
||||
menu-class="auto-scroll"
|
||||
no-caret
|
||||
small
|
||||
title="Colunas"
|
||||
v-rkm-tooltip.hover
|
||||
>
|
||||
<template v-slot:button-content>
|
||||
<rkm-icon icon="columns" />
|
||||
</template>
|
||||
|
||||
<rkm-form-checkbox
|
||||
:indeterminate="indeterminate"
|
||||
@change="handleTodosClick"
|
||||
class="mx-2"
|
||||
v-model="selectedAll"
|
||||
>
|
||||
Todas
|
||||
</rkm-form-checkbox>
|
||||
|
||||
<rkm-form-checkbox-group
|
||||
:options="optionalColumns"
|
||||
class="mx-2"
|
||||
stacked
|
||||
text-field="label"
|
||||
v-model="selectedColumns"
|
||||
value-field="key"
|
||||
/>
|
||||
</rkm-dropdown>
|
||||
|
||||
<rkm-button
|
||||
:disabled="itens.length === 0"
|
||||
@click="handleImprimirClick"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="itens"
|
||||
/>
|
||||
</rkm-area>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, formats, object, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
fields() {
|
||||
return this.columns.filter(column => (column.fixed || false) || this.selectedColumns.includes(column.key))
|
||||
},
|
||||
optionalColumns() {
|
||||
return this.columns.filter(column => !(column.fixed || false))
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
periodo: { required: true },
|
||||
}
|
||||
},
|
||||
requestQueryStringParamsUsuario() {
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(request)
|
||||
},
|
||||
requestQueryStringParamsUsuarioResponsavel() {
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(request)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioHistoricoPapelLotacao: this.getConectaSusRepository('administracao.relatorioHistoricoPapelLotacao'),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
additionals: null,
|
||||
columns: [
|
||||
{
|
||||
class: 'col-min text-center',
|
||||
filterByFormatted: true,
|
||||
fixed: true,
|
||||
formatter: value => this.formatDateTime(value),
|
||||
key: 'historicoDataHora',
|
||||
label: 'Data/Hora',
|
||||
sortable: true,
|
||||
},
|
||||
{key: 'unidadeNomeFantasia', label: 'Unidade', fixed: true, sortable: true },
|
||||
{key: 'infraestruturaNome', label: 'Local de atendimento', fixed: true, sortable: true },
|
||||
{key: 'ocupacaoNome', label: 'CBO', fixed: true, sortable: true },
|
||||
{key: 'papelNome', label: 'Papel', fixed: true, sortable: true },
|
||||
{key: 'acaoNome', label: 'Tipo de ação', fixed: true, sortable: true },
|
||||
{key: 'usuarioNome', label: 'Usuário', fixed: true, sortable: true },
|
||||
{key: 'usuarioResponsavelNome', label: 'Permitido por', sortable: true },
|
||||
],
|
||||
form: null,
|
||||
indeterminate: true,
|
||||
itens: [],
|
||||
model: null,
|
||||
others: {moment},
|
||||
selectedAll: false,
|
||||
selectedColumns: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.create()
|
||||
.then(response => {
|
||||
this.additionals = Object.assign(response.data.additionals)
|
||||
this.form = Object.assign(response.data.form)
|
||||
this.model = Object.assign(response.data.model)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUnidadeChange() {
|
||||
this.form.infraestruturas = []
|
||||
this.form.lotacoes = []
|
||||
this.form.papeis = []
|
||||
this.form.acoes = []
|
||||
this.model.infraestruturaId = null
|
||||
this.model.lotacaoId = null
|
||||
this.model.ocupacaoId = null
|
||||
this.model.papelId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getInfraestruturas()
|
||||
},
|
||||
handleInfraestruturaChange() {
|
||||
this.form.lotacoes = []
|
||||
this.form.papeis = []
|
||||
this.form.acoes = []
|
||||
this.model.lotacaoId = null
|
||||
this.model.ocupacaoId = null
|
||||
this.model.papelId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getLotacoes()
|
||||
},
|
||||
handleLotacaoChange() {
|
||||
this.form.papeis = []
|
||||
this.form.acoes = []
|
||||
this.model.papelId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getPapeis()
|
||||
},
|
||||
handlePapelChange() {
|
||||
this.form.acoes = []
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getAcoes()
|
||||
},
|
||||
handleAcaoChange() {
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
},
|
||||
handleBuscarClick() {
|
||||
this.$refs.RkmForm.validate()
|
||||
.then(valid => {
|
||||
if (valid === false) return
|
||||
|
||||
this.itens = []
|
||||
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.itens = response.data
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
handleLimparClick() {
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.lotacoes = []
|
||||
this.form.papeis = []
|
||||
this.form.acoes = []
|
||||
|
||||
this.model.periodo = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.lotacaoId = null
|
||||
this.model.ocupacaoId = null
|
||||
this.model.papelId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.$nextTick().then(() => this.$refs.RkmForm.resetValidator())
|
||||
},
|
||||
handleTodosClick(selected) {
|
||||
this.selectedColumns = selected ? this.optionalColumns.map(c => c.key) : []
|
||||
},
|
||||
handleImprimirClick() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
...this.request(),
|
||||
selectedColumns: this.fields.map(field => ({
|
||||
class: field.class,
|
||||
key: this.camelToSnake(field.key),
|
||||
label: field.label,
|
||||
})),
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioHistoricoPapelLotacao(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
const content = new Blob([response.data], {type: response.headers['content-type']})
|
||||
const url = URL.createObjectURL(content)
|
||||
const link = document.createElement('a')
|
||||
|
||||
link.href = url
|
||||
link.target = '_blank'
|
||||
link.click()
|
||||
link.remove()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
request() {
|
||||
const model = this.clone(this.model)
|
||||
|
||||
model.periodo.start = this.others.moment(model.periodo.start).format('DD/MM/YYYY')
|
||||
model.periodo.end = this.others.moment(model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return model
|
||||
},
|
||||
getUnidades() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'unidades',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.unidades = Object.assign(response.data.unidades)
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.lotacoes = Object.assign(response.data.lotacoes)
|
||||
this.form.papeis = Object.assign(response.data.papeis)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getInfraestruturas() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'infraestruturas',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.lotacoes = Object.assign(response.data.lotacoes)
|
||||
this.form.papeis = Object.assign(response.data.papeis)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getLotacoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'lotacoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.lotacoes = Object.assign(response.data.lotacoes)
|
||||
this.form.papeis = Object.assign(response.data.papeis)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getPapeis() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'papeis',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.papeis = Object.assign(response.data.papeis)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getAcoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'acoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
mixins: [error, formats, object, repository, stringCase],
|
||||
watch: {
|
||||
'model.periodo': {
|
||||
deep: true,
|
||||
handler(value) {
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.lotacoes = []
|
||||
this.form.papeis = []
|
||||
this.form.acoes = []
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.lotacaoId = null
|
||||
this.model.ocupacaoId = null
|
||||
this.model.papelId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
if (value.start && value.end) {
|
||||
this.getUnidades()
|
||||
}
|
||||
},
|
||||
},
|
||||
'model.usuario': {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
},
|
||||
},
|
||||
'model.usuarioResponsavel': {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.itens = []
|
||||
},
|
||||
},
|
||||
selectedColumns(value) {
|
||||
this.indeterminate = value.length > 0 && value.length != this.optionalColumns.length
|
||||
this.selectedAll = value.length > 0 && value.length == this.optionalColumns.length
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropdown >>> .auto-scroll {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,764 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
v-if="model"
|
||||
ref="RkmForm"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-date-picker
|
||||
:end-validations="validations.periodo"
|
||||
:max-date="additionals.dataAtual"
|
||||
:range-inline="false"
|
||||
:start-validations="validations.periodo"
|
||||
end-label="Até"
|
||||
range
|
||||
start-label="Período de"
|
||||
v-model="model.periodo"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.unidades"
|
||||
@change="handleUnidadeChange"
|
||||
default-option-text="Todas"
|
||||
label="Unidade"
|
||||
show-default-option
|
||||
text-field="nomeFantasia"
|
||||
v-model="model.unidadeId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.infraestruturas"
|
||||
@change="handleInfraestruturaChange"
|
||||
default-option-text="Todos"
|
||||
label="Local de atendimento"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.infraestruturaId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.lotacoes"
|
||||
@change="handleLotacaoChange"
|
||||
default-option-text="Todos"
|
||||
label="CBO"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.lotacaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.modulos"
|
||||
@change="handleModuloChange"
|
||||
default-option-text="Todos"
|
||||
label="Módulo"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.moduloId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.funcionalidades"
|
||||
@change="handleFuncionalidadeChange"
|
||||
default-option-text="Todas"
|
||||
label="Funcionalidade"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.funcionalidadeId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.crudAcoes"
|
||||
@change="handleCrudAcaoChange"
|
||||
default-option-text="Todas"
|
||||
label="Permissão para"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.crudAcaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.acoes"
|
||||
@change="handleAcaoChange"
|
||||
default-option-text="Todas"
|
||||
label="Tipo de ação"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.acaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input-autocomplete
|
||||
:disabled="!model.periodo.start || !model.periodo.end"
|
||||
:repository="repositories.relatorioHistoricoPermissaoLotacao.usuario"
|
||||
:request-query-string-params="requestQueryStringParamsUsuario"
|
||||
:search-fields="[{ key: 'cadastro_cidadao.nome', searchable: true }]"
|
||||
label="Usuário"
|
||||
v-model="model.usuario"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input-autocomplete
|
||||
:disabled="!model.periodo.start || !model.periodo.end"
|
||||
:repository="repositories.relatorioHistoricoPermissaoLotacao.usuarioResponsavel"
|
||||
:request-query-string-params="requestQueryStringParamsUsuarioResponsavel"
|
||||
:search-fields="[{ key: 'cadastro_cidadao.nome', searchable: true }]"
|
||||
label="Permitido por"
|
||||
v-model="model.usuarioResponsavel"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="handleBuscarClick"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="handleLimparClick"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-dropdown
|
||||
class="mr-2"
|
||||
color="primary"
|
||||
cols="1"
|
||||
menu-class="auto-scroll"
|
||||
no-caret
|
||||
small
|
||||
title="Colunas"
|
||||
v-rkm-tooltip.hover
|
||||
>
|
||||
<template v-slot:button-content>
|
||||
<rkm-icon icon="columns" />
|
||||
</template>
|
||||
|
||||
<rkm-form-checkbox
|
||||
:indeterminate="indeterminate"
|
||||
@change="handleTodosClick"
|
||||
class="mx-2"
|
||||
v-model="selectedAll"
|
||||
>
|
||||
Todas
|
||||
</rkm-form-checkbox>
|
||||
|
||||
<rkm-form-checkbox-group
|
||||
:options="optionalColumns"
|
||||
class="mx-2"
|
||||
stacked
|
||||
text-field="label"
|
||||
v-model="selectedColumns"
|
||||
value-field="key"
|
||||
/>
|
||||
</rkm-dropdown>
|
||||
|
||||
<rkm-button
|
||||
:disabled="itens.length === 0"
|
||||
@click="handleImprimirClick"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="itens"
|
||||
/>
|
||||
</rkm-area>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, formats, object, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
fields() {
|
||||
return this.columns.filter(column => (column.fixed || false) || this.selectedColumns.includes(column.key))
|
||||
},
|
||||
optionalColumns() {
|
||||
return this.columns.filter(column => !(column.fixed || false))
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
periodo: { required: true },
|
||||
}
|
||||
},
|
||||
requestQueryStringParamsUsuario() {
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(request)
|
||||
},
|
||||
requestQueryStringParamsUsuarioResponsavel() {
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(request)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioHistoricoPermissaoLotacao: this.getConectaSusRepository('administracao.relatorioHistoricoPermissaoLotacao'),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
additionals: null,
|
||||
columns: [
|
||||
{
|
||||
class: 'col-min text-center',
|
||||
filterByFormatted: true,
|
||||
fixed: true,
|
||||
formatter: value => this.formatDateTime(value),
|
||||
key: 'historicoDataHora',
|
||||
label: 'Data/Hora',
|
||||
sortable: true,
|
||||
},
|
||||
{key: 'unidadeNomeFantasia', label: 'Unidade', sortable: true },
|
||||
{key: 'infraestruturaNome', label: 'Local de atendimento', sortable: true },
|
||||
{key: 'ocupacaoNome', label: 'CBO', sortable: true },
|
||||
{key: 'moduloNome', label: 'Módulo', fixed: true, sortable: true },
|
||||
{key: 'funcionalidadeNome', label: 'Funcionalidade', fixed: true, sortable: true },
|
||||
{key: 'crudAcaoNome', label: 'Permissão para', fixed: true, sortable: true },
|
||||
{key: 'acaoNome', label: 'Tipo de ação', fixed: true, sortable: true },
|
||||
{key: 'usuarioNome', label: 'Usuário', fixed: true, sortable: true },
|
||||
{key: 'usuarioResponsavelNome', label: 'Permitido por', sortable: true },
|
||||
],
|
||||
form: null,
|
||||
indeterminate: true,
|
||||
itens: [],
|
||||
model: null,
|
||||
others: {moment},
|
||||
selectedAll: false,
|
||||
selectedColumns: [
|
||||
'unidadeNomeFantasia',
|
||||
'infraestruturaNome',
|
||||
'ocupacaoNome'
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.create()
|
||||
.then(response => {
|
||||
this.additionals = Object.assign(response.data.additionals)
|
||||
this.form = Object.assign(response.data.form)
|
||||
this.model = Object.assign(response.data.model)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUnidadeChange() {
|
||||
this.form.infraestruturas = []
|
||||
this.form.lotacoes = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.infraestruturaId = null
|
||||
this.model.lotacaoId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getInfraestruturas()
|
||||
},
|
||||
handleInfraestruturaChange() {
|
||||
this.form.lotacoes = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.lotacaoId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getLotacoes()
|
||||
},
|
||||
handleLotacaoChange() {
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getModulos()
|
||||
},
|
||||
handleModuloChange() {
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getFuncionalidades()
|
||||
},
|
||||
handleFuncionalidadeChange() {
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getCrudAcoes()
|
||||
},
|
||||
handleCrudAcaoChange() {
|
||||
this.form.acoes = []
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getAcoes()
|
||||
},
|
||||
handleAcaoChange() {
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
},
|
||||
handleBuscarClick() {
|
||||
this.$refs.RkmForm.validate()
|
||||
.then(valid => {
|
||||
if (valid === false) return
|
||||
|
||||
this.itens = []
|
||||
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.itens = response.data
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
handleLimparClick() {
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.lotacoes = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
|
||||
this.model.periodo = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.lotacaoId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.$nextTick().then(() => this.$refs.RkmForm.resetValidator())
|
||||
},
|
||||
handleTodosClick(selected) {
|
||||
this.selectedColumns = selected ? this.optionalColumns.map(c => c.key) : []
|
||||
},
|
||||
handleImprimirClick() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
...this.request(),
|
||||
selectedColumns: this.fields.map(field => ({
|
||||
class: field.class,
|
||||
key: this.camelToSnake(field.key),
|
||||
label: field.label,
|
||||
})),
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioHistoricoPermissaoLotacao(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
const content = new Blob([response.data], {type: response.headers['content-type']})
|
||||
const url = URL.createObjectURL(content)
|
||||
const link = document.createElement('a')
|
||||
|
||||
link.href = url
|
||||
link.target = '_blank'
|
||||
link.click()
|
||||
link.remove()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
request() {
|
||||
const model = this.clone(this.model)
|
||||
|
||||
model.periodo.start = this.others.moment(model.periodo.start).format('DD/MM/YYYY')
|
||||
model.periodo.end = this.others.moment(model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return model
|
||||
},
|
||||
getUnidades() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'unidades',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.unidades = Object.assign(response.data.unidades)
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.lotacoes = Object.assign(response.data.lotacoes)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getInfraestruturas() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'infraestruturas',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.infraestruturas = Object.assign(response.data.infraestruturas)
|
||||
this.form.lotacoes = Object.assign(response.data.lotacoes)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getLotacoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'lotacoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.lotacoes = Object.assign(response.data.lotacoes)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getModulos() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'modulos',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getFuncionalidades() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'funcionalidades',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getCrudAcoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'crud-acoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getAcoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'acoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
mixins: [error, formats, object, repository, stringCase],
|
||||
watch: {
|
||||
'model.periodo': {
|
||||
deep: true,
|
||||
handler(value) {
|
||||
this.form.unidades = []
|
||||
this.form.infraestruturas = []
|
||||
this.form.lotacoes = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.unidadeId = null
|
||||
this.model.infraestruturaId = null
|
||||
this.model.lotacaoId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuario = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
if (value.start && value.end) {
|
||||
this.getUnidades()
|
||||
}
|
||||
},
|
||||
},
|
||||
'model.usuario': {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
},
|
||||
},
|
||||
'model.usuarioResponsavel': {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.itens = []
|
||||
},
|
||||
},
|
||||
selectedColumns(value) {
|
||||
this.indeterminate = value.length > 0 && value.length != this.optionalColumns.length
|
||||
this.selectedAll = value.length > 0 && value.length == this.optionalColumns.length
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropdown >>> .auto-scroll {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,559 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
v-if="model"
|
||||
ref="RkmForm"
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-date-picker
|
||||
:end-validations="validations.periodo"
|
||||
:max-date="additionals.dataAtual"
|
||||
:range-inline="false"
|
||||
:start-validations="validations.periodo"
|
||||
end-label="Até"
|
||||
range
|
||||
start-label="Período de"
|
||||
v-model="model.periodo"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.papeis"
|
||||
@change="handlePapelChange"
|
||||
default-option-text="Todos"
|
||||
label="Papel"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.papelId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.modulos"
|
||||
@change="handleModuloChange"
|
||||
default-option-text="Todos"
|
||||
label="Módulo"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.moduloId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.funcionalidades"
|
||||
@change="handleFuncionalidadeChange"
|
||||
default-option-text="Todas"
|
||||
label="Funcionalidade"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.funcionalidadeId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.crudAcoes"
|
||||
@change="handleCrudAcaoChange"
|
||||
default-option-text="Todas"
|
||||
label="Permissão para"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.crudAcaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-select
|
||||
:options="form.acoes"
|
||||
@change="handleAcaoChange"
|
||||
default-option-text="Todas"
|
||||
label="Tipo de ação"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.acaoId"
|
||||
value-field='id'
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col>
|
||||
<rkm-form-input-autocomplete
|
||||
:disabled="!model.periodo.start || !model.periodo.end"
|
||||
:repository="repositories.relatorioHistoricoPermissaoPapel.usuarioResponsavel"
|
||||
:request-query-string-params="requestQueryStringParamsUsuarioResponsavel"
|
||||
:search-fields="[{ key: 'cadastro_cidadao.nome', searchable: true }]"
|
||||
label="Permitido por"
|
||||
v-model="model.usuarioResponsavel"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="auto">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="handleBuscarClick"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="handleLimparClick"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-dropdown
|
||||
class="mr-2"
|
||||
color="primary"
|
||||
cols="1"
|
||||
menu-class="auto-scroll"
|
||||
no-caret
|
||||
small
|
||||
title="Colunas"
|
||||
v-rkm-tooltip.hover
|
||||
>
|
||||
<template v-slot:button-content>
|
||||
<rkm-icon icon="columns" />
|
||||
</template>
|
||||
|
||||
<rkm-form-checkbox
|
||||
:indeterminate="indeterminate"
|
||||
@change="handleTodosClick"
|
||||
class="mx-2"
|
||||
v-model="selectedAll"
|
||||
>
|
||||
Todas
|
||||
</rkm-form-checkbox>
|
||||
|
||||
<rkm-form-checkbox-group
|
||||
:options="optionalColumns"
|
||||
class="mx-2"
|
||||
stacked
|
||||
text-field="label"
|
||||
v-model="selectedColumns"
|
||||
value-field="key"
|
||||
/>
|
||||
</rkm-dropdown>
|
||||
|
||||
<rkm-button
|
||||
:disabled="itens.length === 0"
|
||||
@click="handleImprimirClick"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="itens"
|
||||
/>
|
||||
</rkm-area>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, formats, object, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
fields() {
|
||||
return this.columns.filter(column => (column.fixed || false) || this.selectedColumns.includes(column.key))
|
||||
},
|
||||
optionalColumns() {
|
||||
return this.columns.filter(column => !(column.fixed || false))
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
periodo: { required: true },
|
||||
}
|
||||
},
|
||||
requestQueryStringParamsUsuarioResponsavel() {
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(request)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioHistoricoPermissaoPapel: this.getConectaSusRepository('administracao.relatorioHistoricoPermissaoPapel'),
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
additionals: null,
|
||||
columns: [
|
||||
{
|
||||
class: 'col-min text-center',
|
||||
filterByFormatted: true,
|
||||
fixed: true,
|
||||
formatter: value => this.formatDateTime(value),
|
||||
key: 'historicoDataHora',
|
||||
label: 'Data/Hora',
|
||||
sortable: true,
|
||||
},
|
||||
{key: 'papelNome', label: 'Papel', fixed: true, sortable: true },
|
||||
{key: 'moduloNome', label: 'Módulo', fixed: true, sortable: true },
|
||||
{key: 'funcionalidadeNome', label: 'Funcionalidade', fixed: true, sortable: true },
|
||||
{key: 'crudAcaoNome', label: 'Permissão para', fixed: true, sortable: true },
|
||||
{key: 'acaoNome', label: 'Tipo de ação', fixed: true, sortable: true },
|
||||
{key: 'usuarioResponsavelNome', label: 'Permitido por', sortable: true },
|
||||
],
|
||||
form: null,
|
||||
indeterminate: true,
|
||||
itens: [],
|
||||
model: null,
|
||||
others: {moment},
|
||||
selectedAll: false,
|
||||
selectedColumns: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.create()
|
||||
.then(response => {
|
||||
this.additionals = Object.assign(response.data.additionals)
|
||||
this.form = Object.assign(response.data.form)
|
||||
this.model = Object.assign(response.data.model)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handlePapelChange() {
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getModulos()
|
||||
},
|
||||
handleModuloChange() {
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getFuncionalidades()
|
||||
},
|
||||
handleFuncionalidadeChange() {
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getCrudAcoes()
|
||||
},
|
||||
handleCrudAcaoChange() {
|
||||
this.form.acoes = []
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.getAcoes()
|
||||
},
|
||||
handleAcaoChange() {
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
},
|
||||
handleBuscarClick() {
|
||||
this.$refs.RkmForm.validate()
|
||||
.then(valid => {
|
||||
if (valid === false) return
|
||||
|
||||
this.itens = []
|
||||
|
||||
const request = this.clone(this.model)
|
||||
|
||||
request.periodo.start = this.others.moment(this.model.periodo.start).format('DD/MM/YYYY')
|
||||
request.periodo.end = this.others.moment(this.model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.itens = response.data
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
handleLimparClick() {
|
||||
this.form.papeis = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
|
||||
this.model.periodo = {
|
||||
start: null,
|
||||
end: null,
|
||||
}
|
||||
|
||||
this.model.papelId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
this.$nextTick().then(() => this.$refs.RkmForm.resetValidator())
|
||||
},
|
||||
handleTodosClick(selected) {
|
||||
this.selectedColumns = selected ? this.optionalColumns.map(c => c.key) : []
|
||||
},
|
||||
handleImprimirClick() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
...this.request(),
|
||||
selectedColumns: this.fields.map(field => ({
|
||||
class: field.class,
|
||||
key: this.camelToSnake(field.key),
|
||||
label: field.label,
|
||||
})),
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioHistoricoPermissaoPapel(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
const content = new Blob([response.data], {type: response.headers['content-type']})
|
||||
const url = URL.createObjectURL(content)
|
||||
const link = document.createElement('a')
|
||||
|
||||
link.href = url
|
||||
link.target = '_blank'
|
||||
link.click()
|
||||
link.remove()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
request() {
|
||||
const model = this.clone(this.model)
|
||||
|
||||
model.periodo.start = this.others.moment(model.periodo.start).format('DD/MM/YYYY')
|
||||
model.periodo.end = this.others.moment(model.periodo.end).format('DD/MM/YYYY')
|
||||
|
||||
return model
|
||||
},
|
||||
getPapeis() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'papeis',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.papeis = Object.assign(response.data.papeis)
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getModulos() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'modulos',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.modulos = Object.assign(response.data.modulos)
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getFuncionalidades() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'funcionalidades',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.funcionalidades = Object.assign(response.data.funcionalidades)
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getCrudAcoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'crud-acoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.crudAcoes = Object.assign(response.data.crudAcoes)
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getAcoes() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
listar: 'acoes',
|
||||
...this.request(),
|
||||
}
|
||||
|
||||
this.repositories.relatorioHistoricoPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.acoes = Object.assign(response.data.acoes)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
mixins: [error, formats, object, repository, stringCase],
|
||||
watch: {
|
||||
'model.periodo': {
|
||||
deep: true,
|
||||
handler(value) {
|
||||
this.form.papeis = []
|
||||
this.form.modulos = []
|
||||
this.form.funcionalidades = []
|
||||
this.form.crudAcoes = []
|
||||
this.form.acoes = []
|
||||
this.model.papelId = null
|
||||
this.model.moduloId = null
|
||||
this.model.funcionalidadeId = null
|
||||
this.model.crudAcaoId = null
|
||||
this.model.acaoId = null
|
||||
|
||||
this.model.usuarioResponsavel = {
|
||||
id: null,
|
||||
nome: null,
|
||||
}
|
||||
|
||||
this.itens = []
|
||||
|
||||
if (value.start && value.end) {
|
||||
this.getPapeis()
|
||||
}
|
||||
},
|
||||
},
|
||||
'model.usuarioResponsavel': {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.itens = []
|
||||
},
|
||||
},
|
||||
selectedColumns(value) {
|
||||
this.indeterminate = value.length > 0 && value.length != this.optionalColumns.length
|
||||
this.selectedAll = value.length > 0 && value.length == this.optionalColumns.length
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropdown >>> .auto-scroll {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,334 @@
|
||||
<template>
|
||||
<div v-if="model">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.unidades"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleUnidadeClosed"
|
||||
label="Unidades"
|
||||
option-name-key="nomeFantasia"
|
||||
option-text-selecteds="unidade selecionado"
|
||||
v-model="model.unidades"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.infraestruturas"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleInfraestruturaClosed"
|
||||
label="Locais de atendimento"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="local selecionado"
|
||||
v-model="model.infraestruturas"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.papeis"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handlePapelClosed"
|
||||
label="Papéis"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="papel selecionado"
|
||||
v-model="model.papeis"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.usuarios"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleUsuarioClosed"
|
||||
label="Usuários"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="usuário selecionado"
|
||||
v-model="model.usuarios"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.ocupacoes"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleOcupacaoClosed"
|
||||
label="CBO's"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="cbo selecionado"
|
||||
v-model="model.ocupacoes"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="$refs.Form.validate(search)"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="reset"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<template v-if="data">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-button
|
||||
@click="print"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="exportTo"
|
||||
color="info"
|
||||
small
|
||||
title="Exportar"
|
||||
>
|
||||
<rkm-icon icon="file-export" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="data.itens"
|
||||
:sort-by="sortBy"
|
||||
:sort-desc="sortDesc"
|
||||
@sort-changed="onSortChanged"
|
||||
/>
|
||||
</rkm-area>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, file, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories = {
|
||||
exportacao: this.getConectaSusRepository('exportacao.administracao'),
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioPapelLotacao: this.getConectaSusRepository('administracao.relatorioPapelLotacao'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: null,
|
||||
form: null,
|
||||
fields: [
|
||||
{key: 'unidadeNomeFantasia', label: 'Unidade', sortable: true},
|
||||
{key: 'infraestruturaNome', label: 'Local de atendimento', sortable: true},
|
||||
{key: 'papelNome', label: 'Papel', sortable: true},
|
||||
{key: 'usuarioNome', label: 'Usuário', sortable: true},
|
||||
{key: 'ocupacaoNome', label: 'CBO', sortable: true},
|
||||
],
|
||||
model: null,
|
||||
others: {moment},
|
||||
sortBy: 'unidadeNomeFantasia',
|
||||
sortDesc: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPapelLotacao.create()
|
||||
.then((response) => {
|
||||
this.form = response.data.form
|
||||
this.model = response.data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
search() {
|
||||
const request = {
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
papeis: this.model.papeis,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPapelLotacao.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.data = Object.assign(response.data))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
reset() {
|
||||
this.data = null
|
||||
|
||||
this.load()
|
||||
|
||||
this.$nextTick().then(() => this.$refs.Form.resetValidator())
|
||||
},
|
||||
print() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
papeis: this.model.papeis,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioPapelLotacao(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
exportTo() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
papeis: this.model.papeis,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.exportacao.relatorioPapelLotacao(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUnidadeClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'infraestruturas',
|
||||
unidades: this.model.unidades,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.papeis = response.data.papeis
|
||||
this.form.usuarios = response.data.usuarios
|
||||
this.form.ocupacoes = response.data.ocupacoes
|
||||
this.form.infraestruturas = response.data.infraestruturas
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleInfraestruturaClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'papeis',
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.papeis = response.data.papeis
|
||||
this.form.usuarios = response.data.usuarios
|
||||
this.form.ocupacoes = response.data.ocupacoes
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handlePapelClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'usuarios',
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
papeis: this.model.papeis,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = response.data.usuarios
|
||||
this.form.ocupacoes = response.data.ocupacoes
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUsuarioClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'ocupacoes',
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
papeis: this.model.papeis,
|
||||
usuarios: this.model.usuarios,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPapelLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.form.ocupacoes = response.data.ocupacoes)
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleOcupacaoClosed() {
|
||||
this.data = null
|
||||
},
|
||||
onSortChanged(context) {
|
||||
this.sortBy = context.sortBy
|
||||
this.sortDesc = context.sortDesc
|
||||
},
|
||||
},
|
||||
mixins: [error, file, repository, stringCase],
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,375 @@
|
||||
<template>
|
||||
<div v-if="model">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.unidades"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleUnidadeClosed"
|
||||
label="Unidades"
|
||||
option-name-key="nomeFantasia"
|
||||
option-text-selecteds="unidade selecionado"
|
||||
v-model="model.unidades"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.infraestruturas"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleInfraestruturaClosed"
|
||||
label="Locais de atendimento"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="local selecionado"
|
||||
v-model="model.infraestruturas"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.usuarios"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleUsuarioClosed"
|
||||
label="Usuários"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="usuário selecionado"
|
||||
v-model="model.usuarios"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.ocupacoes"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleOcupacaoClosed"
|
||||
label="CBO's"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="cbo selecionado"
|
||||
v-model="model.ocupacoes"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-multiselect
|
||||
:options="form.modulos"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleModuloClosed"
|
||||
label="Módulos"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="módulo selecionado"
|
||||
v-model="model.modulos"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="3">
|
||||
<rkm-form-multiselect
|
||||
:options="form.funcionalidades"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleFuncionalidadeClosed"
|
||||
label="Funcionalidades"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="funcionalidade selecionada"
|
||||
v-model="model.funcionalidades"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="$refs.Form.validate(search)"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="reset"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<template v-if="data">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-button
|
||||
@click="print"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="exportTo"
|
||||
color="info"
|
||||
small
|
||||
title="Exportar"
|
||||
>
|
||||
<rkm-icon icon="file-export" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="data.itens"
|
||||
:sort-by="sortBy"
|
||||
:sort-desc="sortDesc"
|
||||
@sort-changed="onSortChanged"
|
||||
/>
|
||||
</rkm-area>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, file, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories = {
|
||||
exportacao: this.getConectaSusRepository('exportacao.administracao'),
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioPermissaoLotacao: this.getConectaSusRepository('administracao.relatorioPermissaoLotacao'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: null,
|
||||
form: null,
|
||||
fields: [
|
||||
{key: 'unidadeNomeFantasia', label: 'Unidade', sortable: true},
|
||||
{key: 'infraestruturaNome', label: 'Local de atendimento', sortable: true},
|
||||
{key: 'usuarioNome', label: 'Usuário', sortable: true},
|
||||
{key: 'ocupacaoNome', label: 'CBO', sortable: true},
|
||||
{key: 'moduloNome', label: 'Módulo', sortable: true},
|
||||
{key: 'funcionalidadeNome', label: 'Funcionalidade', sortable: true},
|
||||
],
|
||||
model: null,
|
||||
others: {moment},
|
||||
sortBy: 'unidadeNomeFantasia',
|
||||
sortDesc: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.create()
|
||||
.then((response) => {
|
||||
this.form = response.data.form
|
||||
this.model = response.data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
search() {
|
||||
const request = {
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
modulos: this.model.modulos,
|
||||
funcionalidades: this.model.funcionalidades,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.data = Object.assign(response.data))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
reset() {
|
||||
this.data = null
|
||||
|
||||
this.load()
|
||||
|
||||
this.$nextTick().then(() => this.$refs.Form.resetValidator())
|
||||
},
|
||||
print() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
modulos: this.model.modulos,
|
||||
funcionalidades: this.model.funcionalidades,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioPermissaoLotacao(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
exportTo() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
modulos: this.model.modulos,
|
||||
funcionalidades: this.model.funcionalidades,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.exportacao.relatorioPermissaoLotacao(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUnidadeClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'infraestruturas',
|
||||
unidades: this.model.unidades,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.infraestruturas = response.data.infraestruturas
|
||||
this.form.usuarios = response.data.usuarios
|
||||
this.form.ocupacoes = response.data.ocupacoes
|
||||
this.form.modulos = response.data.modulos
|
||||
this.form.funcionalidades = response.data.funcionalidades
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleInfraestruturaClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'modulos',
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.usuarios = response.data.usuarios
|
||||
this.form.ocupacoes = response.data.ocupacoes
|
||||
this.form.modulos = response.data.modulos
|
||||
this.form.funcionalidades = response.data.funcionalidades
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleUsuarioClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'ocupacoes',
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
usuarios: this.model.usuarios,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.ocupacoes = response.data.ocupacoes
|
||||
this.form.modulos = response.data.modulos
|
||||
this.form.funcionalidades = response.data.funcionalidades
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleOcupacaoClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'modulos',
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
usuarios: this.model.usuarios,
|
||||
ocupacoes: this.model.ocupacoes,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.modulos = response.data.modulos
|
||||
this.form.funcionalidades = response.data.funcionalidades
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleModuloClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'funcionalidades',
|
||||
usuarios: this.model.usuarios,
|
||||
unidades: this.model.unidades,
|
||||
infraestruturas: this.model.infraestruturas,
|
||||
modulos: this.model.modulos,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoLotacao.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.form.funcionalidades = response.data.funcionalidades)
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleFuncionalidadeClosed() {
|
||||
this.data = null
|
||||
},
|
||||
onSortChanged(context) {
|
||||
this.sortBy = context.sortBy
|
||||
this.sortDesc = context.sortDesc
|
||||
},
|
||||
},
|
||||
mixins: [error, file, repository, stringCase],
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<div v-if="model">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Filtros"
|
||||
type="fieldset"
|
||||
>
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.papeis"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handlePapelClosed"
|
||||
label="Papéis"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="papel selecionado"
|
||||
v-model="model.papeis"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.modulos"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleModuloClosed"
|
||||
label="Módulos"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="módulo selecionado"
|
||||
v-model="model.modulos"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-multiselect
|
||||
:options="form.funcionalidades"
|
||||
:select-limit="null"
|
||||
@update:dropdownClosed="handleFuncionalidadeClosed"
|
||||
label="Funcionalidades"
|
||||
option-name-key="nome"
|
||||
option-text-selecteds="funcionalidade selecionada"
|
||||
v-model="model.funcionalidades"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="$refs.Form.validate(search)"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="reset"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<template v-if="data">
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-button
|
||||
@click="print"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click="exportTo"
|
||||
color="info"
|
||||
small
|
||||
title="Exportar"
|
||||
>
|
||||
<rkm-icon icon="file-export" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="data.itens"
|
||||
:sort-by="sortBy"
|
||||
:sort-desc="sortDesc"
|
||||
@sort-changed="onSortChanged"
|
||||
/>
|
||||
</rkm-area>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Mixins.
|
||||
import {error, file, repository, stringCase} from '@/mixins'
|
||||
|
||||
// Others.
|
||||
import moment from 'moment'
|
||||
|
||||
// Vuex.
|
||||
import {mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.repositories = {
|
||||
exportacao: this.getConectaSusRepository('exportacao.administracao'),
|
||||
impressao: this.getConectaSusRepository('impressao.administracao'),
|
||||
relatorioPermissaoPapel: this.getConectaSusRepository('administracao.relatorioPermissaoPapel'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: null,
|
||||
form: null,
|
||||
fields: [
|
||||
{key: 'papelNome', label: 'Papel', sortable: true},
|
||||
{key: 'moduloNome', label: 'Módulo', sortable: true},
|
||||
{key: 'funcionalidadeNome', label: 'Funcionalidade', sortable: true},
|
||||
],
|
||||
model: null,
|
||||
others: {moment},
|
||||
sortBy: 'papelNome',
|
||||
sortDesc: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoPapel.create()
|
||||
.then((response) => {
|
||||
this.form = response.data.form
|
||||
this.model = response.data.model
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
search() {
|
||||
const request = {
|
||||
papeis: this.model.papeis,
|
||||
modulos: this.model.modulos,
|
||||
funcionalidades: this.model.funcionalidades,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoPapel.index(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.data = Object.assign(response.data))
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
reset() {
|
||||
this.data = null
|
||||
|
||||
this.load()
|
||||
|
||||
this.$nextTick().then(() => this.$refs.Form.resetValidator())
|
||||
},
|
||||
print() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
papeis: this.model.papeis,
|
||||
modulos: this.model.modulos,
|
||||
funcionalidades: this.model.funcionalidades,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.impressao.relatorioPermissaoPapel(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
exportTo() {
|
||||
this.setLoading()
|
||||
|
||||
const request = {
|
||||
papeis: this.model.papeis,
|
||||
modulos: this.model.modulos,
|
||||
funcionalidades: this.model.funcionalidades,
|
||||
sortBy: this.sortBy ? this.camelToSnake(this.sortBy) : null,
|
||||
sortDesc: this.sortDesc,
|
||||
}
|
||||
|
||||
this.repositories.exportacao.relatorioPermissaoPapel(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(({ data, headers }) => this.openFile(data, headers['content-type']))
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handlePapelClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'modulos',
|
||||
papeis: this.model.papeis,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => {
|
||||
this.form.modulos = response.data.modulos
|
||||
this.form.funcionalidades = response.data.funcionalidades
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleModuloClosed() {
|
||||
this.data = null
|
||||
|
||||
const request = {
|
||||
listar: 'funcionalidades',
|
||||
papeis: this.model.papeis,
|
||||
modulos: this.model.modulos,
|
||||
}
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.relatorioPermissaoPapel.list(this.camelObjectKeysToSnakeRecursive(request))
|
||||
.then(response => this.form.funcionalidades = response.data.funcionalidades)
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleFuncionalidadeClosed() {
|
||||
this.data = null
|
||||
},
|
||||
onSortChanged(context) {
|
||||
this.sortBy = context.sortBy
|
||||
this.sortDesc = context.sortDesc
|
||||
},
|
||||
},
|
||||
mixins: [error, file, repository, stringCase],
|
||||
}
|
||||
</script>
|
||||
113
frontend/src/components/almoxarifado/baixa/List.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-data-table
|
||||
:fields="fields"
|
||||
:repository="repositories.baixa"
|
||||
sort-by="descricao"
|
||||
search-by="descricao"
|
||||
>
|
||||
<template v-slot:cell(isAtivo)="{ item }">
|
||||
{{ item.isAtivo ? 'ATIVO' : 'INATIVO' }}
|
||||
</template>
|
||||
|
||||
<template v-slot:cell(actions)="{ item }">
|
||||
<rkm-button
|
||||
@click.stop="$refs.ModalMaterial.open(item)"
|
||||
authorize="store-almoxarifado-baixa"
|
||||
color="primary"
|
||||
small
|
||||
title="Cadastrar baixa"
|
||||
>
|
||||
<rkm-icon icon="plus" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
@click.stop="$refs.ModalHistorico.open(item)"
|
||||
authorize="reverse-almoxarifado-baixa"
|
||||
color="primary"
|
||||
small
|
||||
title="Histórico de baixa"
|
||||
>
|
||||
<rkm-icon icon="history" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-data-table>
|
||||
|
||||
<ModalMaterial ref="ModalMaterial" />
|
||||
<ModalHistorico ref="ModalHistorico" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import ModalMaterial from './components/material/Modal'
|
||||
import ModalHistorico from './components/historico/Modal'
|
||||
|
||||
// Mixins.
|
||||
import { repository, formats } from '@/mixins'
|
||||
|
||||
export default {
|
||||
components: { ModalMaterial, ModalHistorico },
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
baixa: this.getConectaSusRepository('almoxarifado.baixa')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
|
||||
return [
|
||||
{
|
||||
name: 'cadastroMaterial.codigoMaterial',
|
||||
key: 'codigoMaterial',
|
||||
label: 'Código do material',
|
||||
class: 'col-min',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'descricao',
|
||||
key: 'descricao',
|
||||
label: 'Descrição',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'cadastroGrupo.nome',
|
||||
key: 'grupo',
|
||||
label: 'Grupo',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'cadastroSubgrupo.nome',
|
||||
key: 'subgrupo',
|
||||
label: 'Subgrupo',
|
||||
searchable: true,
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'cadastroMaterial.isAtivo',
|
||||
key: 'isAtivo',
|
||||
label: 'Status',
|
||||
class: 'col-min',
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
label: 'Ações',
|
||||
class: 'col-min'
|
||||
},
|
||||
{
|
||||
name: 'almoxarifadoEntradaItem.codigoBarras',
|
||||
key: 'codigoBarras',
|
||||
label: 'Código de Barras',
|
||||
searchable: true,
|
||||
visible: false,
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
mixins: [ repository, formats ],
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div>
|
||||
<rkm-data-table
|
||||
:fields="fields"
|
||||
:repository="repositories.baixa.history"
|
||||
:request-params="requestParams"
|
||||
:tbody-tr-class="rowClass"
|
||||
class="table-baixas"
|
||||
sort-by="data"
|
||||
>
|
||||
<template v-slot:cell(actions)="{ item }">
|
||||
<rkm-button
|
||||
@click.stop="$refs.ModalDetalhes.open(item)"
|
||||
color="outline-primary"
|
||||
small
|
||||
title="Exibir detalhes"
|
||||
>
|
||||
<rkm-icon icon="align-justify" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:disabled="!!item.estornado"
|
||||
@click.stop="print(item)"
|
||||
color="primary"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:disabled="!!item.estornado"
|
||||
:title="!!item.estornado ? 'Estornado' : 'Estornar'"
|
||||
@click="handleEstorno(item)"
|
||||
color="danger"
|
||||
small
|
||||
>
|
||||
<rkm-icon icon="undo-alt" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<template #afterPagination>
|
||||
<div class="mt-2">
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<p>A linha em <span class="red">vermelho</span> representa uma baixa que foi estornada.</p>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</div>
|
||||
</template>
|
||||
</rkm-data-table>
|
||||
|
||||
<ModalDetalhes ref="ModalDetalhes" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import ModalDetalhes from './components/detalhe/Modal'
|
||||
|
||||
import moment from 'moment'
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
// Mixins.
|
||||
import { repository, error, file } from '@/mixins'
|
||||
|
||||
export default {
|
||||
components: { ModalDetalhes },
|
||||
computed: {
|
||||
requestParams() {
|
||||
|
||||
return { material_id: this.material.id }
|
||||
},
|
||||
fields() {
|
||||
|
||||
return [
|
||||
{
|
||||
name: 'almoxarifadoSaida.createdAt',
|
||||
key: 'data',
|
||||
label: 'Data',
|
||||
searchable: true,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'almoxarifadoMotivoBaixa.descricao',
|
||||
key: 'motivoDescricao',
|
||||
label: 'Motivo',
|
||||
searchable: true,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'cadastroCidadao.nome',
|
||||
key: 'usuarioSolicitanteNome',
|
||||
label: 'Usuário solicitante',
|
||||
searchable: true,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'quantidade',
|
||||
key: 'quantidade',
|
||||
label: 'Quantidade',
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
label: 'Ações',
|
||||
class: 'col-min'
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
baixa: this.getConectaSusRepository('almoxarifado.baixa'),
|
||||
balancete: this.getConectaSusRepository('almoxarifado.balancete'),
|
||||
impressao: this.getConectaSusRepository('impressao.almoxarifado'),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
print({ saidaItemId }) {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
return this.repositories.impressao.baixa(saidaItemId)
|
||||
.then(response => {
|
||||
|
||||
this.openFile(response.data, response.headers['content-type'])
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleEstorno(item) {
|
||||
|
||||
const data = moment(item.data, 'DD/MM/YYYY').format('YYYY-MM-DD')
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.balancete.checkDate(data)
|
||||
.then(({ data }) => {
|
||||
|
||||
if (!data.mesFechado) {
|
||||
|
||||
this.showDeleteConfirmation(
|
||||
'Deseja realmente estornar a baixa?',
|
||||
() => this.repositories.baixa.reverse(item.saidaItemId)
|
||||
.then(() => item.estornado = true),
|
||||
this.handleError
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.showValidationNotification(
|
||||
'A data da baixa corresponde a um mês já finalizado. Estorno não permitido.'
|
||||
)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
rowClass(item, type) {
|
||||
|
||||
if (type === 'row' && item && !!item.estornado) {
|
||||
|
||||
return 'table-danger'
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [ repository, error, file ],
|
||||
props: {
|
||||
material: { type: Object, required: true }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-baixas >>> .red { color: red; }
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<rkm-modal
|
||||
:buttons="['cancel']"
|
||||
:loading="loading"
|
||||
:title="`Histórico de baixa (${material.descricao})`"
|
||||
large
|
||||
ref="Modal"
|
||||
>
|
||||
<List
|
||||
:material="material"
|
||||
ref="List"
|
||||
/>
|
||||
</rkm-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import List from './List'
|
||||
|
||||
// Vuex.
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: { List },
|
||||
computed: {
|
||||
...mapGetters({ loading: 'getLoading' }),
|
||||
},
|
||||
data: () => ({
|
||||
material: {},
|
||||
}),
|
||||
methods: {
|
||||
open(material) {
|
||||
|
||||
this.material = material
|
||||
|
||||
this.$refs.Modal.show()
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<rkm-modal
|
||||
:buttons="['cancel']"
|
||||
:loading="loading"
|
||||
large
|
||||
ref="Modal"
|
||||
title="Detalhes"
|
||||
>
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="items"
|
||||
hide-filters
|
||||
hide-pagination
|
||||
thead-class="d-none"
|
||||
/>
|
||||
</rkm-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Vuex.
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({ loading: 'getLoading' }),
|
||||
fields() {
|
||||
|
||||
return [
|
||||
{
|
||||
key: "field",
|
||||
class: "font-weight-bold col-min",
|
||||
},
|
||||
{
|
||||
key: "value",
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
items: [],
|
||||
}),
|
||||
methods: {
|
||||
open(item) {
|
||||
|
||||
this.items = [
|
||||
{
|
||||
field: 'Data',
|
||||
value: item.data,
|
||||
},
|
||||
{
|
||||
field: 'Motivo',
|
||||
value: item.motivoDescricao,
|
||||
},
|
||||
{
|
||||
field: 'Justificativa',
|
||||
value: item.justificativa || '-',
|
||||
},
|
||||
{
|
||||
field: 'Usuário solicitante',
|
||||
value: item.usuarioSolicitanteNome || '-',
|
||||
},
|
||||
{
|
||||
field: 'Usuário que realizou a baixa',
|
||||
value: item.usuarioBaixaNome,
|
||||
},
|
||||
{
|
||||
field: 'Quantidade',
|
||||
value: item.quantidade,
|
||||
},
|
||||
]
|
||||
|
||||
if (item.usuarioEstornoNome) {
|
||||
|
||||
this.items.push({
|
||||
field: 'Usuário que realizou o estorno',
|
||||
value: item.usuarioEstornoNome,
|
||||
})
|
||||
|
||||
this.items.push({
|
||||
field: 'Data do estorno',
|
||||
value: item.dataEstorno,
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.Modal.show()
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,377 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="loaded">
|
||||
<rkm-form
|
||||
ref="Form"
|
||||
show-legend
|
||||
>
|
||||
<rkm-row>
|
||||
<rkm-col>
|
||||
<rkm-form-select
|
||||
:options="form.motivos"
|
||||
:validations="validations.motivo"
|
||||
label="Motivo"
|
||||
show-default-option
|
||||
textField="descricao"
|
||||
v-model="model.motivoId"
|
||||
valueField="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col
|
||||
v-if="isConsumoInterno"
|
||||
cols="6"
|
||||
>
|
||||
<rkm-form-input-autocomplete
|
||||
:repository="repositories.usuario"
|
||||
:request-query-string-params="autocompleteQueryStringParams.usuarioSolicitante"
|
||||
:search-fields="autocompleteFields.usuarioSolicitante"
|
||||
:validations="validations.usuarioSolicitante"
|
||||
label="Usuário solicitante"
|
||||
uppercase
|
||||
text-field="cidadaoNome"
|
||||
v-model="model.usuarioSolicitante"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row v-if="precisaJustificar">
|
||||
<rkm-col>
|
||||
<rkm-form-input
|
||||
:validations="validations.justificativa"
|
||||
label="Justificativa"
|
||||
uppercase
|
||||
v-model="model.justificativa"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input
|
||||
:value="model.estoque"
|
||||
disabled
|
||||
label="Estoque"
|
||||
>
|
||||
<rkm-input-group-append slot="append">
|
||||
<rkm-button
|
||||
@click.stop="loadEstoque"
|
||||
color="primary"
|
||||
title="Atualizar estoque"
|
||||
v-rkm-tooltip.hover
|
||||
>
|
||||
<rkm-icon icon="sync-alt" />
|
||||
</rkm-button>
|
||||
</rkm-input-group-append>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-input
|
||||
:disabled="!temEstoque"
|
||||
:validations="validations.quantidade"
|
||||
label="Quantidade"
|
||||
v-model="model.quantidade"
|
||||
type="number"
|
||||
>
|
||||
<rkm-input-group-append
|
||||
v-if="form.possuiEntradaComLote"
|
||||
slot="append"
|
||||
>
|
||||
<rkm-button
|
||||
:disabled="!quantidadeValida"
|
||||
@click.stop="$refs.ModalLote.open(model.entradaItens)"
|
||||
title="Visualizar lotes"
|
||||
v-rkm-tooltip.hover
|
||||
>
|
||||
<rkm-icon icon="box-open" />
|
||||
</rkm-button>
|
||||
</rkm-input-group-append>
|
||||
</rkm-form-input>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
|
||||
<ModalLote
|
||||
:model="model"
|
||||
ref="ModalLote"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import ModalLote from '@/components/almoxarifado/components/lote/Modal'
|
||||
|
||||
// Vuex.
|
||||
import { mapActions } from 'vuex'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
// Mixins.
|
||||
import { repository, error, stringCase, object, data, file } from '@/mixins'
|
||||
|
||||
// Enums
|
||||
import motivoBaixaTipo from '@/enums/almoxarifado/motivoBaixaTipo'
|
||||
|
||||
export default {
|
||||
components: { ModalLote },
|
||||
computed: {
|
||||
...mapGetters({ lotacao: 'getLotacao' }),
|
||||
autocompleteFields() {
|
||||
|
||||
return {
|
||||
usuarioSolicitante: [{ key: 'cadastro_cidadao.nome', searchable: true }],
|
||||
}
|
||||
},
|
||||
autocompleteQueryStringParams() {
|
||||
|
||||
return {
|
||||
usuarioSolicitante: {
|
||||
infraestrutura_id: this.lotacao.infraestrutura.id,
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
|
||||
return {
|
||||
motivo: {
|
||||
required: true,
|
||||
},
|
||||
justificativa: {
|
||||
required: this.precisaJustificar,
|
||||
max: 100,
|
||||
},
|
||||
usuarioSolicitante: {
|
||||
required: this.isConsumoInterno
|
||||
},
|
||||
quantidade: {
|
||||
required: true,
|
||||
min_value: 1,
|
||||
max_value: this.model.estoque,
|
||||
},
|
||||
}
|
||||
},
|
||||
precisaJustificar() {
|
||||
|
||||
if (this.model && this.model.motivoId) {
|
||||
|
||||
return !!this.form.motivos.find(m => m.id === this.model.motivoId).justificar
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
isConsumoInterno() {
|
||||
|
||||
if (this.model && this.model.motivoId) {
|
||||
|
||||
return this.form.motivos
|
||||
.find(m => m.id === this.model.motivoId).tipoId === this.enums.motivoBaixaTipo.CONSUMO_INTERNO
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
temEstoque() {
|
||||
|
||||
return this.model && this.model.estoque > 0
|
||||
},
|
||||
quantidadeValida() {
|
||||
|
||||
if (!this.model.quantidade) {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const quantidade = parseInt(this.model.quantidade)
|
||||
|
||||
return quantidade > 0 && quantidade <= this.model.estoque
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
usuario: this.getConectaSusRepository('cadastro.sujeitoAtencao.usuario'),
|
||||
baixa: this.getConectaSusRepository('almoxarifado.baixa'),
|
||||
material: this.getConectaSusRepository('cadastro.material'),
|
||||
impressao: this.getConectaSusRepository('impressao.almoxarifado'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data: () => ({
|
||||
form: null,
|
||||
loaded: false,
|
||||
model: null,
|
||||
enums: { motivoBaixaTipo },
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.baixa.create(this.material.id)
|
||||
.then(({ data }) => {
|
||||
|
||||
this.form = data.form
|
||||
this.model = data.model
|
||||
this.loaded = true
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
save(imprimir = false) {
|
||||
|
||||
this.$refs.Form.validate()
|
||||
.then(valid => {
|
||||
|
||||
if (!valid) return
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.baixa.store(this.prepareData())
|
||||
.then(({ data }) => {
|
||||
|
||||
this.showSaveNotification()
|
||||
|
||||
if (imprimir) {
|
||||
|
||||
this.print(data.id).then(() => this.$emit('save', data))
|
||||
}
|
||||
else {
|
||||
|
||||
this.$emit('save', data)
|
||||
}
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
})
|
||||
},
|
||||
prepareData() {
|
||||
|
||||
const data = this.clone(this.model)
|
||||
|
||||
delete data.estoque
|
||||
|
||||
data.materialId = this.material.id
|
||||
data.quantidade = parseInt(data.quantidade)
|
||||
|
||||
this.createIdKeysToObject(data, ['usuarioSolicitante'])
|
||||
|
||||
data.entradaItens = data.entradaItens
|
||||
.filter(i => i.quantidadeSaida > 0)
|
||||
.map(item => ({
|
||||
entradaItemId: item.entradaItemId,
|
||||
quantidadeSaida: isNaN(parseInt(item.quantidadeSaida)) ? 0 : parseInt(item.quantidadeSaida),
|
||||
}))
|
||||
|
||||
return this.camelObjectKeysToSnakeRecursive(data)
|
||||
},
|
||||
print(saidaId) {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
return this.repositories.impressao.baixa(saidaId)
|
||||
.then(response => {
|
||||
|
||||
this.openFile(response.data, response.headers['content-type'])
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
loadEstoque() {
|
||||
|
||||
this.form.possuiEntradaComLote = false
|
||||
this.model.estoque = 0
|
||||
this.model.entradaItens = []
|
||||
this.model.escolheuEntradaItemManualmente = false
|
||||
this.model.quantidade = null
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.material.getEstoque(this.material.id)
|
||||
.then(({ data }) => {
|
||||
|
||||
this.form.possuiEntradaComLote = data.possuiEntradaComLote
|
||||
|
||||
this.model.estoque = data.total
|
||||
|
||||
this.model.entradaItens = data.porEntrada.map(estoqueEntrada => {
|
||||
|
||||
estoqueEntrada.quantidadeSaida = 0
|
||||
|
||||
return estoqueEntrada
|
||||
})
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
selectEntradaItens() {
|
||||
|
||||
this.model.escolheuEntradaItemManualmente = false
|
||||
|
||||
this.model.entradaItens.map(e => e.quantidadeSaida = 0)
|
||||
|
||||
let quantidade = parseInt(this.model.quantidade)
|
||||
let i = 0
|
||||
|
||||
while (quantidade > 0) {
|
||||
|
||||
const entradaItem = this.model.entradaItens[i]
|
||||
const estoque = parseInt(entradaItem.estoque)
|
||||
|
||||
if (quantidade > estoque) {
|
||||
|
||||
entradaItem.quantidadeSaida = estoque
|
||||
quantidade -= estoque
|
||||
}
|
||||
else {
|
||||
|
||||
entradaItem.quantidadeSaida = quantidade
|
||||
quantidade = 0
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [repository, error, stringCase, object, data, file],
|
||||
props: {
|
||||
material: { type: Object, required: true },
|
||||
},
|
||||
watch: {
|
||||
'precisaJustificar': function (precisa) {
|
||||
|
||||
if (!precisa) {
|
||||
|
||||
this.model.justificativa = null
|
||||
}
|
||||
},
|
||||
'isConsumoInterno': function (isConsumoInterno) {
|
||||
|
||||
if (isConsumoInterno) {
|
||||
|
||||
this.model.usuarioSolicitante = {
|
||||
id: this.lotacao.usuario.id,
|
||||
cidadaoNome: this.lotacao.usuario.cidadao.nome,
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
this.model.usuarioSolicitante = null
|
||||
}
|
||||
},
|
||||
'model.quantidade': function () {
|
||||
|
||||
if (this.form.possuiEntradaComLote && this.quantidadeValida) {
|
||||
|
||||
this.selectEntradaItens()
|
||||
}
|
||||
},
|
||||
'temEstoque': function (temEstoque) {
|
||||
|
||||
this.$emit('has-estoque', temEstoque)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<rkm-modal
|
||||
:loading="loading"
|
||||
:title="`Cadastro de baixa (${material.descricao})`"
|
||||
large
|
||||
ref="Modal"
|
||||
>
|
||||
<Form
|
||||
:material="material"
|
||||
@has-estoque="disableSave = !$event"
|
||||
@save="handleExit"
|
||||
ref="Form"
|
||||
/>
|
||||
|
||||
<template #footer>
|
||||
<rkm-button
|
||||
:disabled="!!loading"
|
||||
@click="handleExit"
|
||||
>
|
||||
Fechar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:disabled="!!loading || disableSave"
|
||||
@click="$refs.Form.save()"
|
||||
color="primary"
|
||||
>
|
||||
Salvar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:disabled="!!loading || disableSave"
|
||||
@click="$refs.Form.save(true)"
|
||||
color="primary"
|
||||
>
|
||||
Salvar e imprimir
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components.
|
||||
import Form from './Form'
|
||||
|
||||
// Vuex.
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: { Form },
|
||||
computed: {
|
||||
...mapGetters({ loading: 'getLoading' }),
|
||||
},
|
||||
data: () => ({
|
||||
material: {},
|
||||
disableSave: true,
|
||||
}),
|
||||
methods: {
|
||||
open(material) {
|
||||
|
||||
this.material = material
|
||||
|
||||
this.$refs.Modal.show()
|
||||
},
|
||||
handleExit() {
|
||||
|
||||
this.$refs.Modal.hide()
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
513
frontend/src/components/almoxarifado/balancete/List.vue
Normal file
@@ -0,0 +1,513 @@
|
||||
<template>
|
||||
<div v-if="loaded">
|
||||
<rkm-alert v-if="additionals.dataUltimoBalanceteFechado">
|
||||
<strong>Último balancete fechado:</strong> {{ additionals.dataUltimoBalanceteFechado }}.
|
||||
</rkm-alert>
|
||||
|
||||
<rkm-area
|
||||
type="fieldset"
|
||||
title="Filtros"
|
||||
>
|
||||
<rkm-form ref="Form">
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-date-picker
|
||||
:end-validations="validations.periodo"
|
||||
:max-date="additionals.dataAtual"
|
||||
:range-inline="false"
|
||||
:start-validations="validations.periodo"
|
||||
end-label="Até"
|
||||
range
|
||||
start-label="Período de"
|
||||
v-model="model.periodo"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:options="form.grupos"
|
||||
default-option-text="Todos"
|
||||
label="Grupo"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.grupoId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
|
||||
<rkm-row>
|
||||
<rkm-col cols="6">
|
||||
<rkm-form-select
|
||||
:disabled="!model.grupoId"
|
||||
:options="subgrupos"
|
||||
default-option-text="Todos"
|
||||
label="Subgrupo"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.subgrupoId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col>
|
||||
<rkm-form-select
|
||||
:options="form.origensProgramaticas"
|
||||
default-option-text="Todas"
|
||||
label="Origem programática"
|
||||
show-default-option
|
||||
text-field="nome"
|
||||
v-model="model.origemProgramaticaId"
|
||||
value-field="id"
|
||||
/>
|
||||
</rkm-col>
|
||||
|
||||
<rkm-col
|
||||
class="text-nowrap"
|
||||
cols="auto"
|
||||
>
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="$refs.Form.validate(search)"
|
||||
color="primary"
|
||||
>
|
||||
Buscar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:label="false"
|
||||
@click="clear"
|
||||
>
|
||||
Limpar
|
||||
</rkm-button>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</rkm-form>
|
||||
</rkm-area>
|
||||
|
||||
<rkm-area
|
||||
no-margin-top
|
||||
title="Resultado"
|
||||
>
|
||||
<template v-slot:trailing>
|
||||
<rkm-dropdown
|
||||
class="mr-2 text-nowrap"
|
||||
color="primary"
|
||||
cols="1"
|
||||
menu-class="auto-scroll"
|
||||
no-caret
|
||||
small
|
||||
title="Colunas"
|
||||
v-rkm-tooltip.hover
|
||||
>
|
||||
<template v-slot:button-content>
|
||||
<rkm-icon icon="columns" />
|
||||
</template>
|
||||
|
||||
<rkm-form-checkbox
|
||||
:indeterminate="indeterminate"
|
||||
:value="true"
|
||||
@change="handleSelectedColumns"
|
||||
class="mx-2"
|
||||
v-model="selectedAll"
|
||||
>
|
||||
Todas
|
||||
</rkm-form-checkbox>
|
||||
|
||||
<rkm-form-checkbox-group
|
||||
:options="columns"
|
||||
class="mx-2"
|
||||
stacked
|
||||
v-model="selectedCols"
|
||||
/>
|
||||
</rkm-dropdown>
|
||||
|
||||
<rkm-button
|
||||
:disabled="itens.length === 0 || !(showSaldoFisico || showSaldoFinanceiro)"
|
||||
@click="print()"
|
||||
color="info"
|
||||
small
|
||||
title="Imprimir"
|
||||
>
|
||||
<rkm-icon icon="print" />
|
||||
</rkm-button>
|
||||
</template>
|
||||
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:foot-clone="itens.length > 0 && (showSaldoFisico || showSaldoFinanceiro)"
|
||||
:items="itens"
|
||||
hide-filters
|
||||
hide-pagination
|
||||
no-footer-sorting
|
||||
>
|
||||
<template
|
||||
v-if="showSaldoFisico || showSaldoFinanceiro"
|
||||
#thead-top
|
||||
>
|
||||
<rkm-tr>
|
||||
<rkm-th
|
||||
:colspan="showMaterial
|
||||
? (showSubgrupo ? 4 : 3)
|
||||
: (showSubgrupo ? 2 : 1)"
|
||||
>
|
||||
</rkm-th>
|
||||
|
||||
<rkm-th
|
||||
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
|
||||
class="text-center text-nowrap"
|
||||
>
|
||||
Saldo anterior
|
||||
</rkm-th>
|
||||
|
||||
<rkm-th
|
||||
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
|
||||
class="text-center"
|
||||
>
|
||||
Entrada
|
||||
</rkm-th>
|
||||
|
||||
<rkm-th
|
||||
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
|
||||
class="text-center"
|
||||
>
|
||||
Saída
|
||||
</rkm-th>
|
||||
|
||||
<rkm-th
|
||||
:colspan="showSaldoFisico && showSaldoFinanceiro ? 2 : 1"
|
||||
class="text-center text-nowrap"
|
||||
>
|
||||
Saldo atual
|
||||
</rkm-th>
|
||||
</rkm-tr>
|
||||
</template>
|
||||
|
||||
<template #foot(materialCodigo)>
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<template #foot(materialDescricao)>
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<template #foot(grupoNome)>
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<template #foot(subgrupoNome)>
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoAnteriorFisico)>
|
||||
<strong>{{ resultado.totalizadores.saldoAnteriorFisico }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoAnteriorFinanceiro)>
|
||||
<strong>{{ resultado.totalizadores.saldoAnteriorFinanceiro }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoEntradaFisico)>
|
||||
<strong>{{ resultado.totalizadores.saldoEntradaFisico }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoEntradaFinanceiro)>
|
||||
<strong>{{ resultado.totalizadores.saldoEntradaFinanceiro }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoSaidaFisico)>
|
||||
<strong>{{ resultado.totalizadores.saldoSaidaFisico }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoSaidaFinanceiro)>
|
||||
<strong>{{ resultado.totalizadores.saldoSaidaFinanceiro }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoAtualFisico)>
|
||||
<strong>{{ resultado.totalizadores.saldoAtualFisico }}</strong>
|
||||
</template>
|
||||
|
||||
<template #foot(saldoAtualFinanceiro)>
|
||||
<strong>{{ resultado.totalizadores.saldoAtualFinanceiro }}</strong>
|
||||
</template>
|
||||
</rkm-table>
|
||||
</rkm-area>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { repository, error } from '@/mixins'
|
||||
import { mapActions } from 'vuex'
|
||||
import moment from 'moment'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
validations() {
|
||||
|
||||
return {
|
||||
periodo: { required: true },
|
||||
}
|
||||
},
|
||||
fields() {
|
||||
|
||||
const codigoMaterial = { key: 'materialCodigo', label: 'Código', sortable: true, class: 'col-min text-center' }
|
||||
const descricaoMaterial = { key: 'materialDescricao', label: 'Material', sortable: true }
|
||||
const nomeGrupo = { key: 'grupoNome', label: 'Grupo', sortable: true }
|
||||
const nomeSubgrupo = { key: 'subgrupoNome', label: 'Subgrupo', sortable: true }
|
||||
const saldoAnteriorFisico = { key: 'saldoAnteriorFisico', label: 'Físico', class: 'col-min text-center' }
|
||||
const saldoAnteriorFinanceiro = { key: 'saldoAnteriorFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
|
||||
const entradaFisico = { key: 'saldoEntradaFisico', label: 'Físico', class: 'col-min text-center' }
|
||||
const entradaFinanceiro = { key: 'saldoEntradaFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
|
||||
const saidaFisico = { key: 'saldoSaidaFisico', label: 'Físico', class: 'col-min text-center' }
|
||||
const saidaFinanceiro = { key: 'saldoSaidaFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
|
||||
const saldoAtualFisico = { key: 'saldoAtualFisico', label: 'Físico', class: 'col-min text-center' }
|
||||
const saldoAtualFinanceiro = { key: 'saldoAtualFinanceiro', label: 'Financeiro', class: 'col-min text-center' }
|
||||
|
||||
let fields = []
|
||||
|
||||
if (this.showMaterial) {
|
||||
|
||||
fields.push(codigoMaterial)
|
||||
fields.push(descricaoMaterial)
|
||||
}
|
||||
|
||||
fields.push(nomeGrupo)
|
||||
|
||||
if (this.showSubgrupo) {
|
||||
|
||||
fields.push(nomeSubgrupo)
|
||||
}
|
||||
|
||||
if (this.showSaldoFisico && this.showSaldoFinanceiro) {
|
||||
|
||||
fields = fields.concat([
|
||||
saldoAnteriorFisico,
|
||||
saldoAnteriorFinanceiro,
|
||||
entradaFisico,
|
||||
entradaFinanceiro,
|
||||
saidaFisico,
|
||||
saidaFinanceiro,
|
||||
saldoAtualFisico,
|
||||
saldoAtualFinanceiro,
|
||||
])
|
||||
}
|
||||
else if (this.showSaldoFisico) {
|
||||
|
||||
fields = fields.concat([
|
||||
saldoAnteriorFisico,
|
||||
entradaFisico,
|
||||
saidaFisico,
|
||||
saldoAtualFisico,
|
||||
])
|
||||
}
|
||||
else if (this.showSaldoFinanceiro) {
|
||||
|
||||
fields = fields.concat([
|
||||
saldoAnteriorFinanceiro,
|
||||
entradaFinanceiro,
|
||||
saidaFinanceiro,
|
||||
saldoAtualFinanceiro,
|
||||
])
|
||||
}
|
||||
|
||||
return fields
|
||||
},
|
||||
subgrupos() {
|
||||
|
||||
if (this.model.grupoId) {
|
||||
|
||||
return this.form.grupos.find(g => g.id === this.model.grupoId).subgrupos
|
||||
}
|
||||
|
||||
return []
|
||||
},
|
||||
showMaterial() {
|
||||
|
||||
return !!this.selectedCols.find(c => c === 'material')
|
||||
},
|
||||
showSubgrupo() {
|
||||
|
||||
return !!this.selectedCols.find(c => c === 'subgrupo')
|
||||
},
|
||||
showSaldoFisico() {
|
||||
|
||||
return !!this.selectedCols.find(c => c === 'saldoFisico')
|
||||
},
|
||||
showSaldoFinanceiro() {
|
||||
|
||||
return !!this.selectedCols.find(c => c === 'saldoFinanceiro')
|
||||
},
|
||||
itens() {
|
||||
|
||||
if (this.showMaterial) {
|
||||
|
||||
return this.resultado.porMaterial
|
||||
}
|
||||
else if (this.showSubgrupo) {
|
||||
|
||||
return this.resultado.porSubgrupo
|
||||
}
|
||||
|
||||
return this.resultado.porGrupo
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
this.repositories = {
|
||||
balancete: this.getConectaSusRepository('almoxarifado.balancete'),
|
||||
impressao: this.getConectaSusRepository('impressao.almoxarifado'),
|
||||
}
|
||||
|
||||
this.load()
|
||||
},
|
||||
data: () => ({
|
||||
loaded: false,
|
||||
additionals: {},
|
||||
form: {},
|
||||
model: {},
|
||||
selectedAll: true,
|
||||
indeterminate: false,
|
||||
resultado: {
|
||||
porMaterial: [],
|
||||
porSubgrupo: [],
|
||||
porGrupo: [],
|
||||
totalizadores: {},
|
||||
},
|
||||
columns: [
|
||||
{ value: 'material', text: 'Material' },
|
||||
{ value: 'subgrupo', text: 'Sugrupo' },
|
||||
{ value: 'saldoFisico', text: 'Saldo físico' },
|
||||
{ value: 'saldoFinanceiro', text: 'Saldo financeiro' },
|
||||
],
|
||||
selectedCols: [
|
||||
'material',
|
||||
'subgrupo',
|
||||
'saldoFisico',
|
||||
'saldoFinanceiro',
|
||||
],
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading']),
|
||||
load() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.balancete.list()
|
||||
.then(({ data }) => {
|
||||
|
||||
this.additionals = data.additionals
|
||||
this.form = data.form
|
||||
this.model = data.model
|
||||
|
||||
this.$emit('additionals-load', this.additionals)
|
||||
|
||||
this.loaded = true
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
search() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.balancete.index(this.getParams())
|
||||
.then(({ data }) => this.resultado = data)
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
clear() {
|
||||
|
||||
this.model.periodo.start = null
|
||||
this.model.periodo.end = null
|
||||
this.model.grupoId = null
|
||||
this.model.subgrupoId = null
|
||||
this.model.origemProgramaticaId = null
|
||||
|
||||
this.$nextTick().then(() => this.$refs.Form.resetValidator())
|
||||
},
|
||||
fecharBalancete() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
this.repositories.balancete.store()
|
||||
.then(() => {
|
||||
|
||||
this.showSaveNotification();
|
||||
this.$emit('save')
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
handleSelectedColumns(selected) {
|
||||
|
||||
if (selected) {
|
||||
|
||||
this.columns
|
||||
.filter(c => !this.selectedCols.includes(c.value))
|
||||
.forEach(c => this.selectedCols.push(c.value))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.selectedCols = []
|
||||
},
|
||||
print() {
|
||||
|
||||
this.setLoading()
|
||||
|
||||
const params = this.getParams()
|
||||
|
||||
params.selectedCols = this.selectedCols
|
||||
|
||||
this.repositories.impressao.balancete(params)
|
||||
.then(response => {
|
||||
|
||||
const content = new Blob([response.data], { type: response.headers['content-type'] })
|
||||
const url = URL.createObjectURL(content)
|
||||
const link = document.createElement('a')
|
||||
|
||||
link.href = url
|
||||
link.target = '_blank'
|
||||
link.click()
|
||||
link.remove()
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
getParams() {
|
||||
|
||||
return {
|
||||
inicio: moment(this.model.periodo.start).format('DD/MM/YYYY'),
|
||||
fim: moment(this.model.periodo.end).format('DD/MM/YYYY'),
|
||||
grupo_id: this.model.grupoId,
|
||||
subgrupo_id: this.model.subgrupoId,
|
||||
origem_programatica_id: this.model.origemProgramaticaId,
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [repository, error],
|
||||
watch: {
|
||||
model: {
|
||||
deep: true,
|
||||
handler() {
|
||||
|
||||
this.resultado = {
|
||||
porMaterial: [],
|
||||
porSubgrupo: [],
|
||||
porGrupo: [],
|
||||
totalizadores: {},
|
||||
}
|
||||
}
|
||||
},
|
||||
'model.grupoId': function () {
|
||||
|
||||
this.model.subgrupoId = null
|
||||
},
|
||||
'selectedCols': function (newValue) {
|
||||
|
||||
this.selectedAll = newValue.length > 0 && newValue.length == this.columns.length
|
||||
this.indeterminate = newValue.length > 0 && newValue.length != this.columns.length
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
170
frontend/src/components/almoxarifado/components/lote/Modal.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<rkm-modal
|
||||
:loading="loading"
|
||||
large
|
||||
ref="Modal"
|
||||
title="Lotes"
|
||||
>
|
||||
<rkm-form ref="Form">
|
||||
<rkm-table
|
||||
:fields="fields"
|
||||
:items="items"
|
||||
hide-filters
|
||||
>
|
||||
<template v-slot:cell(fornecedor.nomeFantasia)="{ value }">
|
||||
{{ value || '-' }}
|
||||
</template>
|
||||
|
||||
<template v-slot:cell(lote)="{ value }">
|
||||
{{ value || '-' }}
|
||||
</template>
|
||||
|
||||
<template v-slot:cell(validadeLote)="{ value }">
|
||||
{{ value || '-' }}
|
||||
</template>
|
||||
|
||||
<template v-slot:cell(quantidadeSaida)="{ item }">
|
||||
<rkm-form-input
|
||||
:validations="getQuantidadeValidation(item)"
|
||||
class="saida my-auto"
|
||||
name="Saída"
|
||||
type="number"
|
||||
v-model="item.quantidadeSaida"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #afterTable>
|
||||
<div class="mt-2">
|
||||
<rkm-row>
|
||||
<rkm-col class="text-right">
|
||||
<h6 class="font-weight-bold mb-0">Quantidade de saídas: {{ quantidadeSaidas }}</h6>
|
||||
</rkm-col>
|
||||
</rkm-row>
|
||||
</div>
|
||||
</template>
|
||||
</rkm-table>
|
||||
</rkm-form>
|
||||
|
||||
<template v-slot:footer>
|
||||
<rkm-button
|
||||
:disabled="!!loading"
|
||||
@click="$refs.Modal.hide()"
|
||||
>
|
||||
Cancelar
|
||||
</rkm-button>
|
||||
|
||||
<rkm-button
|
||||
:disabled="!!loading"
|
||||
@click="save"
|
||||
color="primary"
|
||||
>
|
||||
Salvar
|
||||
</rkm-button>
|
||||
</template>
|
||||
</rkm-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Vuex.
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
// Mixins.
|
||||
import { object } from '@/mixins'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({ loading: 'getLoading' }),
|
||||
fields() {
|
||||
|
||||
return [
|
||||
{ key: 'fornecedor.nomeFantasia', label: 'Fornecedor' },
|
||||
{ key: 'lote', label: 'Lote', class: 'col-min text-center' },
|
||||
{ key: 'validadeLote', label: 'Validade', class: 'col-min text-center' },
|
||||
{ key: 'estoque', label: 'Estoque', class: 'col-min text-center' },
|
||||
{ key: 'quantidadeSaida', label: 'Saída', class: ' col-min text-center' },
|
||||
]
|
||||
},
|
||||
quantidadeSaidas() {
|
||||
|
||||
let quantidadeSaidas = 0
|
||||
|
||||
this.items.forEach(item => {
|
||||
|
||||
const quantidadeSaida = parseInt(item.quantidadeSaida)
|
||||
|
||||
quantidadeSaidas += isNaN(quantidadeSaida) ? 0 : quantidadeSaida
|
||||
})
|
||||
|
||||
return quantidadeSaidas
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
onSave: null,
|
||||
items: []
|
||||
}),
|
||||
methods: {
|
||||
open(entradaItens, onSave = null) {
|
||||
|
||||
this.items = this.clone(entradaItens)
|
||||
this.onSave = onSave
|
||||
|
||||
this.$refs.Modal.show()
|
||||
},
|
||||
save() {
|
||||
|
||||
this.$refs.Form.validate().then(valid => {
|
||||
|
||||
if (!valid) return
|
||||
|
||||
const items = this.items.map(item => {
|
||||
|
||||
const quantidadeSaida = parseInt(item.quantidadeSaida)
|
||||
|
||||
item.quantidadeSaida = isNaN(quantidadeSaida) ? null : quantidadeSaida
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
if (this.model) {
|
||||
|
||||
if (this.quantidadeSaidas != parseInt(this.model[this.quantidadeKey])) {
|
||||
|
||||
this.showValidationNotification(`A soma das saídas deve ser igual a quantidade total informada.
|
||||
Quantidade total informada: ${this.model[this.quantidadeKey]}.`)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.model.entradaItens = this.clone(items)
|
||||
this.model.escolheuEntradaItemManualmente = true
|
||||
}
|
||||
|
||||
if (this.onSave !== null) {
|
||||
|
||||
this.onSave(items)
|
||||
}
|
||||
|
||||
this.$refs.Modal.hide()
|
||||
})
|
||||
},
|
||||
getQuantidadeValidation(item) {
|
||||
|
||||
return {
|
||||
min_value: 0,
|
||||
max_value: item.estoque
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [ object ],
|
||||
props: {
|
||||
model: { type: Object, default: null },
|
||||
quantidadeKey: { type: String, default: 'quantidade' },
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.saida {
|
||||
width: 220px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div v-if="isLoaded">
|
||||
<BoxPaciente
|
||||
ref="BoxPaciente"
|
||||
:data="{ form, model }"
|
||||
/>
|
||||
|
||||
<rkm-tabs
|
||||
v-model="tabIndex"
|
||||
>
|
||||
<rkm-tab
|
||||
title="Dispensação"
|
||||
active
|
||||
>
|
||||
<TabDispensacao
|
||||
ref="TabDispensacao"
|
||||
:form="form"
|
||||
:model="model"
|
||||
@save="handleSave"
|
||||
/>
|
||||
</rkm-tab>
|
||||
|
||||
<rkm-tab
|
||||
title="Histórico"
|
||||
>
|
||||
<TabHistorico
|
||||
ref="TabHistorico"
|
||||
:form="form"
|
||||
/>
|
||||
</rkm-tab>
|
||||
</rkm-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BoxPaciente from '@/components/almoxarifado/paciente/Index'
|
||||
import { repository, object, error, stringCase, data, request, printAlmoxarifado } from '@/mixins'
|
||||
import TabDispensacao from './tabs/Dispensacao'
|
||||
import TabHistorico from './tabs/Historico'
|
||||
import { mapActions } from 'vuex'
|
||||
import moment from 'moment'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BoxPaciente,
|
||||
TabDispensacao,
|
||||
TabHistorico
|
||||
},
|
||||
created() {
|
||||
this.repositories = {
|
||||
dispensacaoMateriais: this.getConectaSusRepository('almoxarifado.dispensacaoMateriais'),
|
||||
}
|
||||
this.load()
|
||||
},
|
||||
data: () => ({
|
||||
tabIndex: 0,
|
||||
isLoaded: false,
|
||||
form: null,
|
||||
model: null
|
||||
}),
|
||||
methods: {
|
||||
...mapActions(['setLoading', 'unsetLoading', 'unsetShowExitFormConfirmation']),
|
||||
load() {
|
||||
if(this.pacienteId) {
|
||||
this.setLoading()
|
||||
this.repositories.dispensacaoMateriais.create(this.pacienteId)
|
||||
.then(({ data }) => {
|
||||
this.setShowDetails(data.form.historico)
|
||||
this.form = this.clone(data.form)
|
||||
this.model = this.clone(data.model)
|
||||
this.isLoaded = true
|
||||
this.$emit('paciente', this.form.paciente)
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
}
|
||||
},
|
||||
setShowDetails(dispensacoes) {
|
||||
dispensacoes.forEach(dispensacao => {
|
||||
dispensacao._showDetails = true
|
||||
})
|
||||
},
|
||||
save() {
|
||||
this.$refs.TabDispensacao.save()
|
||||
},
|
||||
hasModelChanged() {
|
||||
return this.form.historico.some(h => h.items.some(i => !i.estornoSalvo && !!i.estornado)) || this.model.items.length > 0
|
||||
},
|
||||
handleSave() {
|
||||
if(!this.hasModelChanged()) {
|
||||
this.showAlert('Não é possível finalizar, pois nenhuma ação foi realizada.', 'Atenção')
|
||||
return
|
||||
}
|
||||
this.setLoading()
|
||||
this.repositories.dispensacaoMateriais.store(this.prepareData())
|
||||
.then(({ data }) => {
|
||||
if(data.id) {
|
||||
this.showConfirmation("Deseja imprimir o recido do material?",
|
||||
async () => {
|
||||
this.$nextTick()
|
||||
.then(() => this.handlePrint(data))
|
||||
.then(() => this.afterSave())
|
||||
}
|
||||
)
|
||||
} else {
|
||||
this.$nextTick().then(() => this.afterSave())
|
||||
}
|
||||
})
|
||||
.catch(this.handleError)
|
||||
.finally(() => this.unsetLoading())
|
||||
},
|
||||
prepareData() {
|
||||
let estornados = []
|
||||
this.form.historico.forEach(dispensacao => dispensacao.items.forEach(item => {
|
||||
if(!item.estornoSalvo && !!item.estornado) {
|
||||
estornados.push(item.id)
|
||||
}
|
||||
}))
|
||||
return {
|
||||
paciente_id: this.pacienteId,
|
||||
usuario_id: this.model.medicoSolicitante ? this.model.medicoSolicitante.id : null,
|
||||
data_dispensacao: this.model.dataDispensacao ? moment(this.model.dataDispensacao, 'DD/MM/YYYY').format('YYYY-MM-DD') : null,
|
||||
observacao: this.model.observacao,
|
||||
items: this.model.items.map(item => {
|
||||
return {
|
||||
material_id: item.material.id,
|
||||
quantidade: item.quantidade,
|
||||
dispensado_em: moment(item.dispensadoEm, 'DD/MM/YYYY').format('YYYY-MM-DD'),
|
||||
observacao: item.observacao
|
||||
}
|
||||
}),
|
||||
estornados: estornados
|
||||
}
|
||||
},
|
||||
afterSave() {
|
||||
this.$nextTick().then(() => {
|
||||
this.showSaveNotification(
|
||||
null,
|
||||
async () => {
|
||||
this.unsetShowExitFormConfirmation()
|
||||
this.$router.push({ name: 'almoxarifado-dispensacao-materiais-index' })
|
||||
})
|
||||
})
|
||||
},
|
||||
handlePrint(data) {
|
||||
let printData = {
|
||||
medicoNome: this.model.medicoSolicitante.cidadaoNome,
|
||||
materiais: this.model.items,
|
||||
pacienteNome: this.form.paciente.cidadao.nome,
|
||||
pacienteNomeSocial: this.form.paciente.cidadao.nomeSocial,
|
||||
prontuario: this.form.paciente.prontuario,
|
||||
dataNascimento: this.form.paciente.cidadao.dataNascimento.split("-").reverse().join("/"),
|
||||
dataAtual: this.form.dataAtual,
|
||||
dataEntrega: data.dispensadoEm,
|
||||
horaAtendimento: data.horaAtendimento,
|
||||
logotipo: this.form.cliente.logotipo,
|
||||
nomePrefeitura: this.form.cliente.nome,
|
||||
ramoAtividade: this.form.cliente.sistema.ramoAtividade.nome,
|
||||
sistemaNome: this.form.cliente.sistema.nome,
|
||||
sistemaVersao: this.form.cliente.sistema.versao,
|
||||
usuario: this.form.usuario,
|
||||
unidade: this.form.unidade,
|
||||
telefone: this.form.telefone,
|
||||
}
|
||||
this.print().dispensacao(printData)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.tabRefs = [
|
||||
this.$refs.TabDispensacao,
|
||||
this.$refs.TabHistorico,
|
||||
]
|
||||
},
|
||||
mixins: [ repository, object, error, stringCase, data, request, printAlmoxarifado ],
|
||||
props: {
|
||||
pacienteId: { type: Number, required: true }
|
||||
}
|
||||
}
|
||||
</script>
|
||||