cob-cli 2.9.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/customizations/frontend.easy.js +16 -0
- package/package.json +1 -1
- package/templates/dashboards/dash/dist/css/app.3140d0d1.css +8 -0
- package/templates/dashboards/dash/dist/dashboard.html +4 -4
- package/templates/dashboards/dash/dist/js/{app.b5565900.js → app.a65a4c2c.js} +2 -2
- package/templates/dashboards/dash/dist/js/app.a65a4c2c.js.map +1 -0
- package/templates/dashboards/dash/src/App.vue +2 -3
- package/templates/dashboards/dash/src/components/Board.vue +14 -2
- package/templates/dashboards/dash/src/output.css +44978 -284
- package/templates/dashboards/dash/tailwind.config.js +5 -0
- package/templates/frontend/easy/css/_easy/googlefonts.css +360 -0
- package/templates/frontend/easy/css/_easy/vuetify.cob-scoped.css +10488 -0
- package/templates/frontend/easy/js/_easy/lib/axios.min.js +9 -0
- package/templates/frontend/easy/js/_easy/lib/marked.min.js +6 -0
- package/templates/frontend/easy/js/_easy/lib/vue.js +11912 -0
- package/templates/frontend/easy/js/_easy/lib/vue.min.js +6 -0
- package/templates/frontend/easy/js/_easy/lib/vuetify.min.js +6 -0
- package/templates/frontend/easy/js/customizations2.__MERGE__.js +22 -0
- package/templates/frontend/easy/webapp/.browserslistrc +2 -0
- package/templates/frontend/easy/webapp/.eslintrc.js +17 -0
- package/templates/frontend/easy/webapp/README.md +60 -0
- package/templates/frontend/easy/webapp/babel.config.js +5 -0
- package/templates/frontend/easy/webapp/dist/css/app.a4fb91f8.css +1 -0
- package/templates/frontend/easy/webapp/dist/dashboard.html +13 -0
- package/templates/frontend/easy/webapp/dist/js/app.63a57dcd.js +2 -0
- package/templates/frontend/easy/webapp/dist/js/app.63a57dcd.js.map +1 -0
- package/templates/frontend/easy/webapp/package-lock.json +32986 -0
- package/templates/frontend/easy/webapp/package.json +32 -0
- package/templates/frontend/easy/webapp/postcss.config.js +5 -0
- package/templates/frontend/easy/webapp/public/dashboard.html +13 -0
- package/templates/frontend/easy/webapp/src/App.vue +181 -0
- package/templates/frontend/easy/webapp/src/assets/logo.png +0 -0
- package/templates/frontend/easy/webapp/src/components/HelloWorld.vue +59 -0
- package/templates/frontend/easy/webapp/src/components/PermBuilder.vue +163 -0
- package/templates/frontend/easy/webapp/src/components/PlanExecutor.vue +225 -0
- package/templates/frontend/easy/webapp/src/components/ProductPermBuilder.vue +95 -0
- package/templates/frontend/easy/webapp/src/components/RmDefinitionChooser.vue +59 -0
- package/templates/frontend/easy/webapp/src/components/RmDomainChooser.vue +60 -0
- package/templates/frontend/easy/webapp/src/components/RoleBuilder.vue +73 -0
- package/templates/frontend/easy/webapp/src/main.js +19 -0
- package/templates/frontend/easy/webapp/src/perm-templates.js +189 -0
- package/templates/frontend/easy/webapp/src/perms.js +197 -0
- package/templates/frontend/easy/webapp/vue.config.js +66 -0
- package/templates/dashboards/dash/dist/css/app.a16bfc97.css +0 -8
- package/templates/dashboards/dash/dist/js/app.b5565900.js.map +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "userm-easy",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"serve": "vue-cli-service serve",
|
|
7
|
+
"build": "vue-cli-service build",
|
|
8
|
+
"lint": "vue-cli-service lint",
|
|
9
|
+
"dist": "rsync -av --delete dist/* -e ssh $npm_package_config_remote_server:/etc/userm/customUI/$npm_package_config_dash_dir/dist/"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@cob/ui-vue-components": "^2.x",
|
|
13
|
+
"core-js": "^2.6.5",
|
|
14
|
+
"vue": "^2.6.10"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@cob/vue-cli-plugin-dashboard": "latest",
|
|
18
|
+
"@vue/cli-plugin-babel": "^3.12.0",
|
|
19
|
+
"@vue/cli-plugin-eslint": "^3.12.0",
|
|
20
|
+
"@vue/cli-service": "^3.12.0",
|
|
21
|
+
"babel-eslint": "^10.0.1",
|
|
22
|
+
"eslint": "^5.16.0",
|
|
23
|
+
"eslint-plugin-vue": "^5.0.0",
|
|
24
|
+
"stylus": "^0.54.0",
|
|
25
|
+
"stylus-loader": "^3.0.0",
|
|
26
|
+
"vue-template-compiler": "^2.6.10"
|
|
27
|
+
},
|
|
28
|
+
"config": {
|
|
29
|
+
"remote_server": "dogfooding.cultofbits.com",
|
|
30
|
+
"dash_dir": "easy"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<% for (var css in htmlWebpackPlugin.files.css) { %>
|
|
2
|
+
<link href="<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
|
|
3
|
+
<% } %>
|
|
4
|
+
|
|
5
|
+
<div id="userm-easy"></div>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
cob.utils.afterDeps([ 'Vue', 'Vuetify', 'axios', 'marked' ], function() {
|
|
9
|
+
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
|
|
10
|
+
cob.utils.loadScript('<%=htmlWebpackPlugin.files.chunks[chunk].entry%>');
|
|
11
|
+
<% } %>
|
|
12
|
+
})
|
|
13
|
+
</script>
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-app>
|
|
3
|
+
<v-container fluid grid-list-sm>
|
|
4
|
+
|
|
5
|
+
<v-layout row wrap>
|
|
6
|
+
<v-flex m12 xs12>
|
|
7
|
+
<h3 style="text-align:center;margin-top:10px;">Easy Perms</h3>
|
|
8
|
+
</v-flex>
|
|
9
|
+
|
|
10
|
+
<v-flex md3 sm6 xs12>
|
|
11
|
+
<v-switch v-model="showTemplates" label="Templates" hide-details></v-switch>
|
|
12
|
+
</v-flex>
|
|
13
|
+
<v-flex md3 sm6 xs12>
|
|
14
|
+
<v-switch v-model="showBuilder" label="Builder" hide-details></v-switch>
|
|
15
|
+
</v-flex>
|
|
16
|
+
<v-flex md3 sm6 xs12>
|
|
17
|
+
<v-switch v-model="showPlan" label="Plan" hide-details></v-switch>
|
|
18
|
+
</v-flex>
|
|
19
|
+
<v-flex md3 sm6 xs12>
|
|
20
|
+
<v-switch v-model="debug" label="debug" hide-details></v-switch>
|
|
21
|
+
</v-flex>
|
|
22
|
+
</v-layout>
|
|
23
|
+
|
|
24
|
+
<v-layout v-if="showTemplates" row wrap>
|
|
25
|
+
|
|
26
|
+
<!-- Seleccionar template -->
|
|
27
|
+
<v-flex xs12>
|
|
28
|
+
<v-select :items="permTemplates"
|
|
29
|
+
v-model="selectedTemplate"
|
|
30
|
+
item-text="name" return-object
|
|
31
|
+
label="Escolha um template" clearable dense solo></v-select>
|
|
32
|
+
</v-flex>
|
|
33
|
+
|
|
34
|
+
<!-- Template -->
|
|
35
|
+
<v-layout xs12 column v-if="selectedTemplate">
|
|
36
|
+
<v-flex xs12 v-if="debug">
|
|
37
|
+
{{ selectedTemplate }}
|
|
38
|
+
</v-flex>
|
|
39
|
+
|
|
40
|
+
<v-layout xs12 row wrap align-center
|
|
41
|
+
v-for="tmplVar in selectedTemplate.vars"
|
|
42
|
+
v-bind:key="tmplVar.name">
|
|
43
|
+
<v-flex md2 sm3 xs12>{{ tmplVar.name }} : {{ tmplVar.type }}</v-flex>
|
|
44
|
+
<v-flex md10 sm9 xs12>
|
|
45
|
+
<v-text-field v-if="tmplVar.type === 'simple'"
|
|
46
|
+
v-model="tmplVar.value"></v-text-field>
|
|
47
|
+
<RmDefinitionChooser v-if="tmplVar.type === 'RM-DEF'"
|
|
48
|
+
v-model="tmplVar.value"></RmDefinitionChooser>
|
|
49
|
+
<RmDomainChooser v-if="tmplVar.type === 'RM-DOMAIN-ID'"
|
|
50
|
+
v-model="tmplVar.value"></RmDomainChooser>
|
|
51
|
+
</v-flex>
|
|
52
|
+
</v-layout>
|
|
53
|
+
</v-layout>
|
|
54
|
+
|
|
55
|
+
<v-flex xs12>
|
|
56
|
+
<v-btn color="primary"
|
|
57
|
+
:disabled="selectedTemplate == null"
|
|
58
|
+
v-on:click="applyTemplate">Apply Template</v-btn>
|
|
59
|
+
</v-flex>
|
|
60
|
+
</v-layout>
|
|
61
|
+
|
|
62
|
+
<!-- Builder -->
|
|
63
|
+
<v-flex xs12 v-if="showBuilder">
|
|
64
|
+
<ProductPermBuilder :perms="perms" :debug="debug" v-model="rmPerms"/>
|
|
65
|
+
</v-flex>
|
|
66
|
+
|
|
67
|
+
<v-flex md1 xs12 v-if="showBuilder">
|
|
68
|
+
<v-btn color="primary" v-on:click="plan">Planear</v-btn>
|
|
69
|
+
</v-flex>
|
|
70
|
+
|
|
71
|
+
<!-- Creator -->
|
|
72
|
+
<PlanExecutor v-if="showPlan" :value="rmPerms" :debug="debug"></PlanExecutor>
|
|
73
|
+
</v-container>
|
|
74
|
+
|
|
75
|
+
</v-app>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<script>
|
|
79
|
+
import ProductPermBuilder from './components/ProductPermBuilder.vue';
|
|
80
|
+
import RmDefinitionChooser from './components/RmDefinitionChooser.vue';
|
|
81
|
+
import RmDomainChooser from './components/RmDomainChooser.vue';
|
|
82
|
+
import PlanExecutor from './components/PlanExecutor.vue';
|
|
83
|
+
|
|
84
|
+
import permTemplates from './perm-templates.js';
|
|
85
|
+
import perms from './perms.js';
|
|
86
|
+
|
|
87
|
+
const applyAllSubstitutions = function(value, subs){
|
|
88
|
+
return subs.reduce(
|
|
89
|
+
(acc, curr) => {
|
|
90
|
+
// verdade para entidades complexas como Defs, Domains, etc...
|
|
91
|
+
if(typeof curr.value === 'object'){
|
|
92
|
+
acc = acc.replace(`$$${curr.name}.ID$$`, curr.value.id)
|
|
93
|
+
acc = acc.replace(`$$${curr.name}.NAME$$`, curr.value.name)
|
|
94
|
+
} else {
|
|
95
|
+
acc = acc.replace(`$$${curr.name}$$`, curr.value)
|
|
96
|
+
}
|
|
97
|
+
return acc;
|
|
98
|
+
} ,
|
|
99
|
+
value
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default {
|
|
104
|
+
name: 'app',
|
|
105
|
+
components: {
|
|
106
|
+
ProductPermBuilder,
|
|
107
|
+
RmDomainChooser,
|
|
108
|
+
RmDefinitionChooser,
|
|
109
|
+
PlanExecutor
|
|
110
|
+
},
|
|
111
|
+
data() {
|
|
112
|
+
return {
|
|
113
|
+
debug: false,
|
|
114
|
+
showTemplates: false,
|
|
115
|
+
showBuilder: true,
|
|
116
|
+
showPlan: false,
|
|
117
|
+
|
|
118
|
+
permTemplates: permTemplates,
|
|
119
|
+
selectedTemplate: null,
|
|
120
|
+
|
|
121
|
+
perms: perms,
|
|
122
|
+
|
|
123
|
+
rmPerms: {
|
|
124
|
+
product: "recordm",
|
|
125
|
+
perms: [
|
|
126
|
+
{ name: "", description: ''}
|
|
127
|
+
],
|
|
128
|
+
roles: [ ]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
methods: {
|
|
134
|
+
applyTemplate: function(){
|
|
135
|
+
// todo jone tornar isto num ciclo
|
|
136
|
+
const vars = this.selectedTemplate.vars
|
|
137
|
+
const newPerms = JSON.parse(JSON.stringify(this.selectedTemplate.productPerms[0]))
|
|
138
|
+
|
|
139
|
+
newPerms.perms = newPerms.perms.map(p => ({
|
|
140
|
+
name: applyAllSubstitutions(p.name, vars),
|
|
141
|
+
description: applyAllSubstitutions(p.description, vars)
|
|
142
|
+
}))
|
|
143
|
+
|
|
144
|
+
newPerms.roles = newPerms.roles.map(r => ({
|
|
145
|
+
name: applyAllSubstitutions(r.name, vars),
|
|
146
|
+
description: applyAllSubstitutions(r.description, vars),
|
|
147
|
+
perms: r.perms.map(p => applyAllSubstitutions(p, vars))
|
|
148
|
+
}))
|
|
149
|
+
|
|
150
|
+
this.rmPerms = newPerms
|
|
151
|
+
|
|
152
|
+
this.showTemplates = false;
|
|
153
|
+
this.showBuilder = true;
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
plan() {
|
|
157
|
+
this.showBuilder = false;
|
|
158
|
+
this.showPlan = true;
|
|
159
|
+
},
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
</script>
|
|
163
|
+
|
|
164
|
+
<style>
|
|
165
|
+
#app {
|
|
166
|
+
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
|
167
|
+
-webkit-font-smoothing: antialiased;
|
|
168
|
+
-moz-osx-font-smoothing: grayscale;
|
|
169
|
+
//text-align: center;
|
|
170
|
+
color: #2c3e50;
|
|
171
|
+
font-size: 1.2em;
|
|
172
|
+
}
|
|
173
|
+
#app .v-input input,
|
|
174
|
+
#app .v-input textarea,
|
|
175
|
+
#app .v-input .v-select__selection {
|
|
176
|
+
font-size: 0.9em;
|
|
177
|
+
min-height: fit-content;
|
|
178
|
+
}
|
|
179
|
+
</style>
|
|
180
|
+
|
|
181
|
+
<!-- vim: set sw=2 ts=2 et : -->
|
|
Binary file
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="hello">
|
|
3
|
+
<h1>{{ msg }}</h1>
|
|
4
|
+
<p>
|
|
5
|
+
For a guide and recipes on how to configure / customize this project,<br>
|
|
6
|
+
check out the
|
|
7
|
+
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
8
|
+
</p>
|
|
9
|
+
<h3>Installed CLI Plugins</h3>
|
|
10
|
+
<ul>
|
|
11
|
+
<li><a href="https://www.npmjs.com/package/@cob%2Fvue-cli-plugin-dashboard" target="_blank" rel="noopener">dashboard</a></li>
|
|
12
|
+
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
13
|
+
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
|
14
|
+
</ul>
|
|
15
|
+
<h3>Essential Links</h3>
|
|
16
|
+
<ul>
|
|
17
|
+
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
18
|
+
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
19
|
+
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
20
|
+
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
21
|
+
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
22
|
+
</ul>
|
|
23
|
+
<h3>Ecosystem</h3>
|
|
24
|
+
<ul>
|
|
25
|
+
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
26
|
+
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
27
|
+
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
28
|
+
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
29
|
+
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
30
|
+
</ul>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
export default {
|
|
36
|
+
name: 'HelloWorld',
|
|
37
|
+
props: {
|
|
38
|
+
msg: String
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
44
|
+
<style scoped>
|
|
45
|
+
h3 {
|
|
46
|
+
margin: 40px 0 0;
|
|
47
|
+
}
|
|
48
|
+
ul {
|
|
49
|
+
list-style-type: none;
|
|
50
|
+
padding: 0;
|
|
51
|
+
}
|
|
52
|
+
li {
|
|
53
|
+
display: inline-block;
|
|
54
|
+
margin: 0 10px;
|
|
55
|
+
}
|
|
56
|
+
a {
|
|
57
|
+
color: #42b983;
|
|
58
|
+
}
|
|
59
|
+
</style>
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-layout column>
|
|
3
|
+
<v-layout row wrap>
|
|
4
|
+
|
|
5
|
+
<v-flex sm3 xs12>
|
|
6
|
+
<v-combobox v-model="domain" :items="selectableDomains" @change="actions = []"
|
|
7
|
+
label="Domain" dense clearable></v-combobox>
|
|
8
|
+
</v-flex>
|
|
9
|
+
|
|
10
|
+
<v-flex sm4 xs12>
|
|
11
|
+
<v-combobox v-model="actions" :items="selectableActions" @change="entities = []"
|
|
12
|
+
label="Action" dense multiple clearable></v-combobox>
|
|
13
|
+
</v-flex>
|
|
14
|
+
|
|
15
|
+
<v-flex sm5 xs12>
|
|
16
|
+
<v-combobox v-if="!customEntityType" v-model="entities" :items="selectableEntities"
|
|
17
|
+
label="Entity" dense multiple clearable></v-combobox>
|
|
18
|
+
<RmDomainChooser v-if="customEntityType === 'RM-DOMAIN-ID'"
|
|
19
|
+
v-model="customEntity"></RmDomainChooser>
|
|
20
|
+
<RmDefinitionChooser v-if="customEntityType === 'RM-DEF'"
|
|
21
|
+
v-model="customEntity"></RmDefinitionChooser>
|
|
22
|
+
</v-flex>
|
|
23
|
+
</v-layout>
|
|
24
|
+
|
|
25
|
+
<v-flex xs12>
|
|
26
|
+
<v-textarea md3 v-model="description"
|
|
27
|
+
label="Description" rows="1" auto-grow></v-textarea>
|
|
28
|
+
</v-flex>
|
|
29
|
+
|
|
30
|
+
<v-layout v-if="debug" row wrap>
|
|
31
|
+
<v-flex sm2 xs12>
|
|
32
|
+
domain: {{ domain }}
|
|
33
|
+
</v-flex>
|
|
34
|
+
|
|
35
|
+
<v-flex sm4 xs12 style="background-color: #efe">
|
|
36
|
+
actions: {{ actions }}
|
|
37
|
+
</v-flex>
|
|
38
|
+
|
|
39
|
+
<v-flex sm3 xs12>
|
|
40
|
+
entities: {{ customEntityType ? "custom" : "normal" }} {{ customEntityType ? customEntity : entities }}
|
|
41
|
+
</v-flex>
|
|
42
|
+
|
|
43
|
+
</v-layout>
|
|
44
|
+
|
|
45
|
+
<!-- needed to force de compute and emit of the resulting perm -->
|
|
46
|
+
<span style="display:none">{{ resultingPerm }}</span>
|
|
47
|
+
</v-layout>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<script>
|
|
51
|
+
|
|
52
|
+
import RmDomainChooser from './RmDomainChooser.vue'
|
|
53
|
+
import RmDefinitionChooser from './RmDefinitionChooser.vue'
|
|
54
|
+
|
|
55
|
+
export default {
|
|
56
|
+
name: 'PermBuilder',
|
|
57
|
+
|
|
58
|
+
components: {
|
|
59
|
+
RmDomainChooser, RmDefinitionChooser
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
props: {
|
|
63
|
+
perms: Array,
|
|
64
|
+
value: Object,
|
|
65
|
+
debug: Boolean
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
data() {
|
|
69
|
+
const components = this.value.name.split(":");
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
domain: components[0] || '',
|
|
73
|
+
components: components,
|
|
74
|
+
actions: components.length > 1 ? components[1].split(',') : [],
|
|
75
|
+
entities: components.length > 2 ? components[2].split(',') : []
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
computed: {
|
|
80
|
+
|
|
81
|
+
selectableDomains: function(){
|
|
82
|
+
return this.perms.map(d => d.domain);
|
|
83
|
+
},
|
|
84
|
+
selectableActions: function(){
|
|
85
|
+
const selectedDomain = this.perms.find(d => d.domain === this.domain)
|
|
86
|
+
const domainActions = ( selectedDomain || {} ).actions || [];
|
|
87
|
+
return domainActions.map(a => a.name);
|
|
88
|
+
},
|
|
89
|
+
customEntityType() {
|
|
90
|
+
const selectedDomain = this.perms.find(d => d.domain === this.domain)
|
|
91
|
+
if(typeof selectedDomain === 'undefined' ) return false;
|
|
92
|
+
|
|
93
|
+
const entities = selectedDomain.actions
|
|
94
|
+
.filter(a => this.actions.includes(a.name))
|
|
95
|
+
.flatMap(a => (a.entities || []) )
|
|
96
|
+
|
|
97
|
+
return entities.length > 0 && entities[0].type
|
|
98
|
+
},
|
|
99
|
+
customEntity: {
|
|
100
|
+
get: function(){
|
|
101
|
+
return this.customEntityType && this.components.length > 2 ? { id: this.components[2] } : {id: null}
|
|
102
|
+
},
|
|
103
|
+
set: function(newValue) {
|
|
104
|
+
this.entities = [newValue]
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
selectableEntities: function(){
|
|
108
|
+
const selectedDomain = this.perms.find(d => d.domain === this.domain)
|
|
109
|
+
if(typeof selectedDomain === 'undefined' ) return [];
|
|
110
|
+
|
|
111
|
+
const selectedActions = selectedDomain.actions
|
|
112
|
+
.filter(a => this.actions.includes(a.name))
|
|
113
|
+
const actionEntities = selectedActions.flatMap(a => (a.entities || []) )
|
|
114
|
+
.map(e => e.name);
|
|
115
|
+
|
|
116
|
+
return actionEntities || [ "*" ];
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
description: {
|
|
120
|
+
get: function(){
|
|
121
|
+
return this.value.description
|
|
122
|
+
},
|
|
123
|
+
set: function(newValue){
|
|
124
|
+
this.value.description = newValue;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
resultingPerm: function(){
|
|
129
|
+
const result = this.buildName();
|
|
130
|
+
|
|
131
|
+
if(this.value.name !== result){
|
|
132
|
+
this.$emit('input', { name: result, description: this.description });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
methods: {
|
|
140
|
+
buildName: function(){
|
|
141
|
+
var result = '';
|
|
142
|
+
|
|
143
|
+
if(this.domain && this.domain != '')
|
|
144
|
+
result += this.domain;
|
|
145
|
+
|
|
146
|
+
if(this.actions.length > 0)
|
|
147
|
+
result += ':' + this.actions.join(",");
|
|
148
|
+
|
|
149
|
+
if(this.entities.length > 0){
|
|
150
|
+
if(this.customEntityType)
|
|
151
|
+
result += ':' + this.entities.map(e => e.id || e).join(",");
|
|
152
|
+
else
|
|
153
|
+
result += ':' + this.entities.join(",");
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
</script>
|
|
160
|
+
|
|
161
|
+
<style></style>
|
|
162
|
+
|
|
163
|
+
<!-- vim: set sw=2 ts=2 et : -->
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-layout xs12 row wrap align-center>
|
|
3
|
+
<v-flex xs12>
|
|
4
|
+
<h3>Plano</h3>
|
|
5
|
+
</v-flex>
|
|
6
|
+
|
|
7
|
+
<v-flex v-if="debug" xs12 style="text-align:left;">
|
|
8
|
+
<code>{{ value }}</code>
|
|
9
|
+
</v-flex>
|
|
10
|
+
|
|
11
|
+
<v-flex md5 xs12>
|
|
12
|
+
<v-layout column>
|
|
13
|
+
<v-flex xs12 text-center>
|
|
14
|
+
<h4>Permissões</h4>
|
|
15
|
+
</v-flex>
|
|
16
|
+
<v-layout row v-for="perm in perms" v-bind:key="perm.name">
|
|
17
|
+
<v-flex xs3 text-right :class="'state-' + perm.state">
|
|
18
|
+
{{ perm.state }}
|
|
19
|
+
<span v-if="perm.state === 'existing'">
|
|
20
|
+
[<a :href="'#/permission/' + perm.id" target="_blank">{{ perm.id }}</a>]
|
|
21
|
+
</span>
|
|
22
|
+
<span v-if="perm.state === 'error'"><pre>{{ perm.error }}</pre></span>
|
|
23
|
+
</v-flex>
|
|
24
|
+
<v-flex xs12 text-left>
|
|
25
|
+
<code>{{ perm.name }}</code>
|
|
26
|
+
</v-flex>
|
|
27
|
+
</v-layout>
|
|
28
|
+
</v-layout>
|
|
29
|
+
</v-flex>
|
|
30
|
+
|
|
31
|
+
<v-flex md7 xs12>
|
|
32
|
+
<v-layout column>
|
|
33
|
+
<v-flex xs12 text-center>
|
|
34
|
+
<h4>Roles</h4>
|
|
35
|
+
</v-flex>
|
|
36
|
+
<v-layout row align-start fill-height v-for="role in roles" v-bind:key="role.name">
|
|
37
|
+
<v-flex xs2 text-right :class="'state-' + role.state">
|
|
38
|
+
{{ role.state }}
|
|
39
|
+
<span v-if="role.state === 'existing'">
|
|
40
|
+
[<a :href="'#/role/' + role.id" target="_blank">{{ role.id }}</a>]
|
|
41
|
+
</span>
|
|
42
|
+
<span v-if="role.state === 'error'"><pre>{{ role.error }}</pre></span>
|
|
43
|
+
</v-flex>
|
|
44
|
+
<v-flex md4 xs12 text-left>
|
|
45
|
+
<code>{{ role.name }}</code>
|
|
46
|
+
</v-flex>
|
|
47
|
+
<v-flex md6 xs12 text-left>
|
|
48
|
+
com perms: {{ role.perms }}
|
|
49
|
+
</v-flex>
|
|
50
|
+
</v-layout>
|
|
51
|
+
</v-layout>
|
|
52
|
+
</v-flex>
|
|
53
|
+
|
|
54
|
+
<v-flex xs12 style="padding-top:20px">
|
|
55
|
+
<v-btn v-on:click="refresh">Refresh Cache</v-btn>
|
|
56
|
+
<v-btn color="primary" v-on:click="execute">Executar</v-btn>
|
|
57
|
+
</v-flex>
|
|
58
|
+
</v-layout>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<script>
|
|
62
|
+
import axios from 'axios';
|
|
63
|
+
|
|
64
|
+
export default {
|
|
65
|
+
name: 'PlanExecutor',
|
|
66
|
+
|
|
67
|
+
props: {
|
|
68
|
+
value: Object,
|
|
69
|
+
debug: Boolean
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
data() {
|
|
73
|
+
return {
|
|
74
|
+
waitingToCreateRoles: false
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
computed: {
|
|
79
|
+
plan() {
|
|
80
|
+
return this.value
|
|
81
|
+
},
|
|
82
|
+
perms() {
|
|
83
|
+
this.find('permission', this.plan.perms)
|
|
84
|
+
|
|
85
|
+
return this.plan.perms
|
|
86
|
+
},
|
|
87
|
+
roles() {
|
|
88
|
+
this.find('role', ( this.plan.roles || [] ))
|
|
89
|
+
|
|
90
|
+
return this.plan.roles || []
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
watch: {
|
|
95
|
+
waitingToCreateRoles() {
|
|
96
|
+
if(this.waitingToCreateRoles && this.perms.every(p => p.state !== 'new')){
|
|
97
|
+
this.createRoles();
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
perms() {
|
|
101
|
+
if(this.waitingToCreateRoles && this.perms.every(p => p.state !== 'new')){
|
|
102
|
+
this.createRoles();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
methods: {
|
|
108
|
+
|
|
109
|
+
find: function(type, entities, force){
|
|
110
|
+
entities.forEach((p, i) => {
|
|
111
|
+
if(!force && p.state) return;
|
|
112
|
+
|
|
113
|
+
axios.get('/userm/userm/' + type + '/product/recordm/name/' + encodeURIComponent(p.name))
|
|
114
|
+
.then((resp) => {
|
|
115
|
+
this.$set(entities[i], 'state', 'existing')
|
|
116
|
+
this.$set(entities[i], 'id', resp.data.id)
|
|
117
|
+
})
|
|
118
|
+
.catch(() => {
|
|
119
|
+
this.$set(entities[i], 'state', 'new')
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
refresh: function(){
|
|
125
|
+
this.find('permission', this.plan.perms, true)
|
|
126
|
+
this.find('role', ( this.plan.roles || [] ), true)
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
execute: function(){
|
|
130
|
+
this.waitingToCreateRoles = true;
|
|
131
|
+
this.createPerms();
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
createPerms: function(){
|
|
135
|
+
const product = this.plan.product;
|
|
136
|
+
const perms = this.perms;
|
|
137
|
+
const uri = 'userm/permission'
|
|
138
|
+
|
|
139
|
+
const newPerms = perms.filter(p => p.state === 'new');
|
|
140
|
+
|
|
141
|
+
newPerms.forEach(p => {
|
|
142
|
+
const body = {
|
|
143
|
+
product: product,
|
|
144
|
+
name: p.name,
|
|
145
|
+
description: p.description
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
axios.post(uri, body)
|
|
149
|
+
.then(function(resp){
|
|
150
|
+
this.$set(p, 'state', 'existing')
|
|
151
|
+
this.$set(p, 'id', resp.data.id)
|
|
152
|
+
}.bind(this))
|
|
153
|
+
|
|
154
|
+
.catch(function(error){
|
|
155
|
+
window.console.error('JN perm', error)
|
|
156
|
+
this.$set(p, 'state', 'error')
|
|
157
|
+
this.$set(p, 'error', error.response.data)
|
|
158
|
+
}.bind(this))
|
|
159
|
+
})
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
createRoles: function(){
|
|
163
|
+
this.waitingToCreateRoles = false;
|
|
164
|
+
|
|
165
|
+
const product = this.plan.product;
|
|
166
|
+
const roles = this.roles;
|
|
167
|
+
const uri = 'userm/role'
|
|
168
|
+
|
|
169
|
+
const newRoles = roles.filter(r => r.state === 'new' || r.state === 'error' );
|
|
170
|
+
|
|
171
|
+
if(newRoles.length === 0){
|
|
172
|
+
roles.forEach(r => this.associateRoles(r.id, r.perms));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
newRoles.forEach(r => {
|
|
176
|
+
const body = {
|
|
177
|
+
product: product,
|
|
178
|
+
name: r.name,
|
|
179
|
+
description: r.description
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
axios.post(uri, body)
|
|
183
|
+
.then(function(resp){
|
|
184
|
+
this.$set(r, 'state', 'existing')
|
|
185
|
+
this.$set(r, 'id', resp.data.id)
|
|
186
|
+
|
|
187
|
+
this.associateRoles(r.id, r.perms);
|
|
188
|
+
|
|
189
|
+
}.bind(this))
|
|
190
|
+
|
|
191
|
+
.catch(function(error){
|
|
192
|
+
window.console.error('JN role', error)
|
|
193
|
+
this.$set(r, 'state', 'error')
|
|
194
|
+
this.$set(r, 'error', error.response.data)
|
|
195
|
+
}.bind(this))
|
|
196
|
+
})
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
associateRoles: function(roleId, permNames){
|
|
200
|
+
const permIds = permNames.map(name => this.perms.find(p => p.name === name).id)
|
|
201
|
+
window.console.debug('JN', 'associate', roleId, permNames, permIds);
|
|
202
|
+
|
|
203
|
+
axios.put('userm/role/' + roleId + '/permissions', permIds)
|
|
204
|
+
.then(resp => {
|
|
205
|
+
window.console.debug('JN', 'associar', resp)
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
</script>
|
|
212
|
+
<style scoped>
|
|
213
|
+
.state-new {
|
|
214
|
+
color: green
|
|
215
|
+
}
|
|
216
|
+
.state-existing {
|
|
217
|
+
color: gray
|
|
218
|
+
}
|
|
219
|
+
.state-error {
|
|
220
|
+
color: red
|
|
221
|
+
}
|
|
222
|
+
div, span, code {
|
|
223
|
+
font-size: 1.0em;
|
|
224
|
+
}
|
|
225
|
+
</style>
|