cob-cli 2.8.1 → 2.12.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.
Files changed (91) hide show
  1. package/customizations/dashboard.dash.js +11 -0
  2. package/customizations/dashboard.js +1 -0
  3. package/customizations/dashboard.simple.js +1 -1
  4. package/customizations/dashboard.vue.empty.js +1 -1
  5. package/customizations/frontend.easy.js +16 -0
  6. package/lib/task_lists/customize_copy.js +7 -6
  7. package/package.json +1 -1
  8. package/templates/{cob-dashboard-html → dashboards/cob-dashboard-html}/demoDashboard.html +0 -0
  9. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/package-lock.json +0 -0
  10. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/package.json +0 -0
  11. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/src/App.vue +0 -0
  12. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/src/dashboard.html +0 -0
  13. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/src/main.js +0 -0
  14. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/src/plugins/cobUiVueComponents.js +0 -0
  15. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/src/plugins/vuetify.js +0 -0
  16. package/templates/{cob-dashboard-vue → dashboards/cob-dashboard-vue}/vue.config.js +0 -0
  17. package/templates/dashboards/dash/dist/css/app.2ca409ad.css +8 -0
  18. package/templates/dashboards/dash/dist/dashboard.html +20 -0
  19. package/templates/dashboards/dash/dist/fonts/fa-brands-400.a78ffbbe.ttf +0 -0
  20. package/templates/dashboards/dash/dist/fonts/fa-brands-400.cd2b4095.woff2 +0 -0
  21. package/templates/dashboards/dash/dist/fonts/fa-regular-400.b1a1bebb.ttf +0 -0
  22. package/templates/dashboards/dash/dist/fonts/fa-regular-400.e8a1ba41.woff2 +0 -0
  23. package/templates/dashboards/dash/dist/fonts/fa-solid-900.55b416a8.woff2 +0 -0
  24. package/templates/dashboards/dash/dist/fonts/fa-solid-900.73820155.ttf +0 -0
  25. package/templates/dashboards/dash/dist/fonts/fa-v4compatibility.0d6f5f18.ttf +0 -0
  26. package/templates/dashboards/dash/dist/fonts/fa-v4compatibility.786e6b33.woff2 +0 -0
  27. package/templates/dashboards/dash/dist/js/app.a65a4c2c.js +188 -0
  28. package/templates/dashboards/dash/dist/js/app.a65a4c2c.js.map +1 -0
  29. package/templates/dashboards/dash/package-lock.json +24340 -0
  30. package/templates/dashboards/dash/package.json +19 -0
  31. package/templates/dashboards/dash/src/App.vue +257 -0
  32. package/templates/dashboards/dash/src/Dashboard.vue +46 -0
  33. package/templates/dashboards/dash/src/assets/css/all.min.css +6 -0
  34. package/templates/dashboards/dash/src/assets/webfonts/fa-brands-400.ttf +0 -0
  35. package/templates/dashboards/dash/src/assets/webfonts/fa-brands-400.woff2 +0 -0
  36. package/templates/dashboards/dash/src/assets/webfonts/fa-regular-400.ttf +0 -0
  37. package/templates/dashboards/dash/src/assets/webfonts/fa-regular-400.woff2 +0 -0
  38. package/templates/dashboards/dash/src/assets/webfonts/fa-solid-900.ttf +0 -0
  39. package/templates/dashboards/dash/src/assets/webfonts/fa-solid-900.woff2 +0 -0
  40. package/templates/dashboards/dash/src/assets/webfonts/fa-v4compatibility.ttf +0 -0
  41. package/templates/dashboards/dash/src/assets/webfonts/fa-v4compatibility.woff2 +0 -0
  42. package/templates/dashboards/dash/src/collector.js +3782 -0
  43. package/templates/dashboards/dash/src/components/Board.vue +61 -0
  44. package/templates/dashboards/dash/src/components/BoardsNav.vue +23 -0
  45. package/templates/dashboards/dash/src/components/BoardsPage.vue +36 -0
  46. package/templates/dashboards/dash/src/components/Menu.vue +19 -0
  47. package/templates/dashboards/dash/src/components/Title.vue +13 -0
  48. package/templates/dashboards/dash/src/components/Totals.vue +53 -0
  49. package/templates/dashboards/dash/src/components/TotalsBadge.vue +69 -0
  50. package/templates/dashboards/dash/src/dashboard.html +34 -0
  51. package/templates/dashboards/dash/src/definition_dashboard_v59.json +394 -0
  52. package/templates/dashboards/dash/src/input.css +9 -0
  53. package/templates/dashboards/dash/src/main.js +11 -0
  54. package/templates/dashboards/dash/src/output.css +135974 -0
  55. package/templates/dashboards/dash/tailwind.config.js +19 -0
  56. package/templates/dashboards/dash/vue.config.js +104 -0
  57. package/templates/frontend/common/css/_dashboard.css +7 -0
  58. package/templates/frontend/common/css/_global.css +3 -2
  59. package/templates/frontend/easy/css/_easy/googlefonts.css +360 -0
  60. package/templates/frontend/easy/css/_easy/vuetify.cob-scoped.css +10488 -0
  61. package/templates/frontend/easy/js/_easy/lib/axios.min.js +9 -0
  62. package/templates/frontend/easy/js/_easy/lib/marked.min.js +6 -0
  63. package/templates/frontend/easy/js/_easy/lib/vue.js +11912 -0
  64. package/templates/frontend/easy/js/_easy/lib/vue.min.js +6 -0
  65. package/templates/frontend/easy/js/_easy/lib/vuetify.min.js +6 -0
  66. package/templates/frontend/easy/js/customizations2.__MERGE__.js +22 -0
  67. package/templates/frontend/easy/webapp/.browserslistrc +2 -0
  68. package/templates/frontend/easy/webapp/.eslintrc.js +17 -0
  69. package/templates/frontend/easy/webapp/README.md +60 -0
  70. package/templates/frontend/easy/webapp/babel.config.js +5 -0
  71. package/templates/frontend/easy/webapp/dist/css/app.a4fb91f8.css +1 -0
  72. package/templates/frontend/easy/webapp/dist/dashboard.html +13 -0
  73. package/templates/frontend/easy/webapp/dist/js/app.63a57dcd.js +2 -0
  74. package/templates/frontend/easy/webapp/dist/js/app.63a57dcd.js.map +1 -0
  75. package/templates/frontend/easy/webapp/package-lock.json +32986 -0
  76. package/templates/frontend/easy/webapp/package.json +32 -0
  77. package/templates/frontend/easy/webapp/postcss.config.js +5 -0
  78. package/templates/frontend/easy/webapp/public/dashboard.html +13 -0
  79. package/templates/frontend/easy/webapp/src/App.vue +181 -0
  80. package/templates/frontend/easy/webapp/src/assets/logo.png +0 -0
  81. package/templates/frontend/easy/webapp/src/components/HelloWorld.vue +59 -0
  82. package/templates/frontend/easy/webapp/src/components/PermBuilder.vue +163 -0
  83. package/templates/frontend/easy/webapp/src/components/PlanExecutor.vue +225 -0
  84. package/templates/frontend/easy/webapp/src/components/ProductPermBuilder.vue +95 -0
  85. package/templates/frontend/easy/webapp/src/components/RmDefinitionChooser.vue +59 -0
  86. package/templates/frontend/easy/webapp/src/components/RmDomainChooser.vue +60 -0
  87. package/templates/frontend/easy/webapp/src/components/RoleBuilder.vue +73 -0
  88. package/templates/frontend/easy/webapp/src/main.js +19 -0
  89. package/templates/frontend/easy/webapp/src/perm-templates.js +189 -0
  90. package/templates/frontend/easy/webapp/src/perms.js +197 -0
  91. package/templates/frontend/easy/webapp/vue.config.js +66 -0
@@ -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,5 @@
1
+ module.exports = {
2
+ plugins: {
3
+ autoprefixer: {}
4
+ }
5
+ }
@@ -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 : -->
@@ -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>