@nixweb/nixloc-ui 0.0.292 → 0.0.294

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.
@@ -1,103 +1,160 @@
1
1
  <template>
2
2
  <div>
3
- <div :class="['sidebar', { collapsed: isSidebarCollapsed }]">
3
+ <div :class="['sidebar', { collapsed: menuCollapsed }]">
4
4
  <div class="sidebar-header">
5
- <span class="header-logo">
6
- <img src="https://espaco.blob.core.windows.net/nixloc-photo-user/E29W4HNYQG_10.png"
7
- alt="CodingNepal" />
5
+ <span class="header-logo" @click="editProfile">
6
+ <img class="photo" :src="urlPhoto" />
8
7
  </span>
9
- <button class="sidebar-toggler" @click="toggleSidebar">
10
- <span class="material-symbols-rounded icon-menu-arrow">
11
- <i class="fa-solid fa-angle-left"></i>
8
+ <Button class="sidebar-toggler" @click="toggleSidebar">
9
+ <span>
10
+ <i v-if="menuCollapsed" class="fa-solid fa-angle-right icon-menu-arrow"></i>
11
+ <i v-else class="fa-solid fa-angle-left icon-menu-arrow"></i>
12
12
  </span>
13
- </button>
13
+ </Button>
14
14
  </div>
15
-
16
- <div :class="{ sub: isSidebarCollapsed }">
17
- <div v-for="(item, index) in menuFilter(true)">
18
- <div>
19
- <div v-if="isSidebarCollapsed" class="molded-icon text-center"
20
- @mouseover="handleMouseOver(item.title, item.module)">
21
- <i :class="item.icon"></i>
22
- </div>
23
- <div class="molded-icon-open" v-else @click="toggleSubMenu(item.title, item.module)">
24
- <b-row>
25
- <b-col sm="1">
26
- <i :class="item.icon"></i>
27
- </b-col>
28
- <b-col sm="8">
29
- <span class="title-menu">{{ item.title }} </span>
30
- </b-col>
31
- <b-col sm="1">
32
- <div>
33
- <i v-if="titleSubMenu == item.title" class="fa-sharp fa-solid fa-angle-down"
34
- :class="{ 'rotate': titleSubMenu == item.title }"></i>
35
-
36
- <i v-else class="fa-sharp fa-solid fa-angle-down"
37
- :class="{ 'rotate-down': titleSubMenu != item.title }"></i>
38
- </div>
39
- </b-col>
40
- </b-row>
15
+ <div v-if="menuCollapsed">
16
+ <br><br>
17
+ </div>
18
+ <ScrollBar :minHeight="pageSize" :maxHeight="pageSize">
19
+ <div :class="{ 'sub': menuCollapsed }">
20
+ <div v-for="(item, index) in menuFilter(true)">
21
+ <div>
22
+ <div :ref="item.title" v-if="menuCollapsed" class="molded-icon text-center" :class="{
23
+ 'menu-active': moduleActive === item.module,
24
+ 'module-selected': module === item.module
25
+ }" @mouseover="handleMouseOver(item.title, item.module)">
26
+ <i :class="item.icon"></i>
27
+ </div>
28
+ <div class="molded-icon-open" :class="{
29
+ 'menu-active': moduleActive === item.module
30
+ }" v-else @click="toggleSubMenu(item.title, item.module)">
31
+ <b-row>
32
+ <b-col sm="1">
33
+ <i :class="item.icon"></i>
34
+ </b-col>
35
+ <b-col sm="8">
36
+ <span class="title-menu">{{ item.title }} </span>
37
+ </b-col>
38
+ <b-col sm="1">
39
+ <div>
40
+ <i v-if="titleSubMenu == item.title" class="fa-sharp fa-solid fa-angle-down"
41
+ :class="{ 'rotate': titleSubMenu == item.title }"></i>
42
+
43
+ <i v-else class="fa-sharp fa-solid fa-angle-down"
44
+ :class="{ 'rotate-down': titleSubMenu != item.title }"></i>
45
+ </div>
46
+ </b-col>
47
+ </b-row>
48
+ </div>
41
49
  </div>
42
- </div>
43
50
 
44
-
45
- <transition name="slide-fade">
46
- <div class="sub-menu" v-if="!isSidebarCollapsed && titleSubMenu == item.title">
47
- <div v-for="(item, index) in subMenuFilter(false)" :key="index">
48
- <div v-if="item.title" class="sub-menu-title" @click.prevent="navegateTo(item)">
49
- <b-row>
50
- <b-col sm="3"> <i :class="item.icon"></i></b-col>
51
- <span> {{ item.title }}</span>
52
- </b-row>
51
+ <transition name="slide-fade">
52
+ <div class="sub-menu" v-if="!menuCollapsed && titleSubMenu == item.title">
53
+ <div v-for="(item, index) in subMenuFilter(false)" :key="index">
54
+ <div v-if="item.title" class="sub-menu-title"
55
+ @click.prevent="navegateTo(item, item.module)">
56
+ <b-row>
57
+ <b-col sm="3"> <i :class="item.icon"></i></b-col>
58
+ <span> {{ item.title }}</span>
59
+ </b-row>
60
+ </div>
53
61
  </div>
54
62
  </div>
55
- </div>
56
- </transition>
57
-
58
- <transition name="slide-fade">
59
- <div class="sub-menu-collapsed sub-menu" @mouseleave="handleMouseLeave"
60
- v-if="isSidebarCollapsed && titleSubMenuCollapsed == item.title">
61
- <div v-for="(item, index) in subMenuFilter(false)" :key="index">
62
- <div v-if="item.title" class="sub-menu-title-collapsed"
63
- @click.prevent="navegateTo(item)">
64
- <b-row>
65
- <b-col sm="3"> <i :class="item.icon"></i></b-col>
66
- <span> {{ item.title }}</span>
67
- </b-row>
63
+ </transition>
64
+
65
+ <transition name="slide-fade">
66
+ <div :ref="item.title + 'sub'" class="sub-menu-collapsed sub-menu"
67
+ v-if="menuCollapsed && titleSubMenuCollapsed == item.title">
68
+ <div v-for="(item, index) in subMenuFilter(false)" :key="index">
69
+ <div :class="{ 'sub-menu-title-collapsed': item.title }"
70
+ @click.prevent="navegateTo(item, item.module)">
71
+ <b-row>
72
+ <b-col sm="2" v-if="item.title">
73
+ <i :class="item.icon"></i>
74
+ </b-col>
75
+ <b-col sm="9">
76
+ <div v-if="item.groupName" class="div-group">
77
+ {{ item.groupName }}
78
+ </div>
79
+ <span> {{ item.title }}</span>
80
+ </b-col>
81
+ </b-row>
82
+ </div>
68
83
  </div>
69
84
  </div>
70
- </div>
71
- </transition>
85
+ </transition>
86
+ </div>
87
+ <br>
88
+ <br>
89
+ <br>
72
90
  </div>
73
- </div>
91
+ </ScrollBar>
92
+
74
93
  </div>
75
94
  </div>
76
95
  </template>
77
96
 
78
97
  <script>
79
98
 
99
+ import ScrollBar from "@nixweb/nixloc-ui/src/component/layout/ScrollBar.vue";
100
+
80
101
  import { mapState, mapMutations, mapGetters } from "vuex";
81
102
 
82
103
  export default {
104
+ props: {
105
+ urlPhoto: String,
106
+ },
107
+ components: {
108
+ ScrollBar
109
+ },
83
110
  data() {
84
111
  return {
85
112
  module: "",
86
- isSidebarCollapsed: false,
113
+ moduleActive: "",
114
+ isSidebarCollapsed: true,
87
115
  openDropdowns: {},
88
116
  titleSubMenu: "",
89
117
  titleSubMenuCollapsed: "",
118
+ pageSize: 0,
119
+ distanceFromBottom: 0,
90
120
  };
91
121
  },
122
+ mounted() {
123
+ this.updatePageSize();
124
+ window.addEventListener('resize', this.updatePageSize);
125
+
126
+ if (!localStorage.getItem('menuCollapsed')) {
127
+ localStorage.setItem('menuCollapsed', this.isSidebarCollapsed ? "closed" : "open");
128
+ }
129
+
130
+ if (localStorage.getItem('menuCollapsed') === 'open') {
131
+ this.toggleMenu(false);
132
+ } else {
133
+ this.toggleMenu(true);
134
+ }
135
+
136
+ if (this.$route.matched[0])
137
+ this.moduleActive = this.$route.matched[0].props.default.module;
138
+
139
+ },
140
+ beforeDestroy() {
141
+ window.removeEventListener('resize', this.updatePageSize);
142
+ },
92
143
  computed: {
93
144
  ...mapState("user", ["menu", "userLogged"]),
145
+ ...mapState("generic", ["menuCollapsed"]),
94
146
  ...mapGetters("generic", ["event"]),
95
147
  },
96
148
  methods: {
97
- ...mapMutations("generic", ["addEvent"]),
149
+ ...mapMutations("generic", ["addEvent", "toggleMenu"]),
150
+ updatePageSize() {
151
+ const windowHeight = window.innerHeight;
152
+ this.pageSize = windowHeight;
153
+ },
98
154
  toggleSidebar() {
99
155
  this.isSidebarCollapsed = !this.isSidebarCollapsed;
100
- this.addEvent({ name: "isSidebarCollapsed", data: this.isSidebarCollapsed });
156
+ this.toggleMenu(this.isSidebarCollapsed);
157
+ localStorage.setItem('menuCollapsed', this.isSidebarCollapsed ? "closed" : "open");
101
158
  this.titleSubMenu = "";
102
159
  this.titleSubMenuCollapsed = "";
103
160
  },
@@ -112,9 +169,25 @@ export default {
112
169
  handleMouseOver(title, module) {
113
170
  this.module = module;
114
171
  this.titleSubMenuCollapsed = title;
172
+
173
+ var divSub = this.$refs[title + 'sub'];
174
+
175
+ if (divSub) {
176
+ let self = this;
177
+ setTimeout(function () {
178
+ const heightSubMenu = divSub[0].getBoundingClientRect();
179
+
180
+ if (heightSubMenu.top < 0 || heightSubMenu.left < 0 || heightSubMenu.bottom > window.innerHeight || heightSubMenu.right > window.innerWidth) {
181
+ divSub[0].style.bottom = '0px';
182
+ }
183
+
184
+ }, 100);
185
+ }
115
186
  },
116
187
  handleMouseLeave() {
117
188
  this.titleSubMenuCollapsed = "";
189
+ if (this.menuCollapsed)
190
+ this.module = "";
118
191
  },
119
192
  menuFilter(isModule) {
120
193
  let filter = [];
@@ -137,13 +210,33 @@ export default {
137
210
  });
138
211
  return filter;
139
212
  },
140
- navegateTo(item) {
213
+ navegateTo(item, module) {
141
214
  this.$router.push({
142
215
  name: item.routeName,
143
216
  });
144
- this.titleSubMenu = "";
217
+
218
+ this.moduleActive = module;
145
219
  this.titleSubMenuCollapsed = "";
146
220
  },
221
+ editProfile() {
222
+ this.addEvent({ name: "clickedProfile" });
223
+ },
224
+ },
225
+ watch: {
226
+ event: {
227
+ handler: function (event) {
228
+ if (event.name == "handleMouseOver") {
229
+ this.handleMouseLeave();
230
+ }
231
+ },
232
+ deep: true,
233
+ },
234
+ $route: {
235
+ handler: function (router) {
236
+ this.moduleActive = router.matched[0].props.default.module;
237
+ },
238
+ deep: true,
239
+ },
147
240
  },
148
241
  };
149
242
  </script>
@@ -153,11 +246,12 @@ export default {
153
246
  position: fixed;
154
247
  top: 0;
155
248
  left: 0;
156
- z-index: 10;
157
- width: 270px;
249
+ width: 275px;
158
250
  height: 100vh;
159
- background: #577696;
251
+ border-radius: 0px 20px 0px 0px;
252
+ background-color: #577696;
160
253
  transition: all 0.4s ease;
254
+ z-index: 1000;
161
255
  }
162
256
 
163
257
  .sidebar.collapsed {
@@ -177,15 +271,16 @@ export default {
177
271
  height: 46px;
178
272
  display: block;
179
273
  object-fit: contain;
274
+ cursor: pointer;
180
275
  border-radius: 50%;
181
276
  }
182
277
 
183
278
  .sidebar-header .sidebar-toggler,
184
279
  .sidebar-menu-button {
185
280
  position: absolute;
186
- right: 20px;
187
- height: 35px;
188
- width: 35px;
281
+ right: 23px;
282
+ height: 30px;
283
+ width: 30px;
189
284
  color: #151A2D;
190
285
  border: none;
191
286
  cursor: pointer;
@@ -193,7 +288,7 @@ export default {
193
288
  background: #EEF2FF;
194
289
  align-items: center;
195
290
  justify-content: center;
196
- border-radius: 8px;
291
+ border-radius: 50px;
197
292
  transition: 0.4s ease;
198
293
  }
199
294
 
@@ -201,96 +296,6 @@ export default {
201
296
  transform: translate(-4px, 65px);
202
297
  }
203
298
 
204
- .sidebar-header .sidebar-toggler span,
205
- .sidebar-menu-button span {
206
- font-size: 1.75rem;
207
- transition: 0.4s ease;
208
- }
209
-
210
- .sidebar.collapsed .sidebar-header .sidebar-toggler span {
211
- transform: rotate(180deg);
212
- }
213
-
214
- .sidebar-header .sidebar-toggler:hover {
215
- background: #d9e1fd;
216
- }
217
-
218
- .sidebar-nav .nav-list {
219
- list-style: none;
220
- display: flex;
221
- gap: 4px;
222
- padding: 0 15px;
223
- flex-direction: column;
224
- transform: translateY(15px);
225
- transition: 0.4s ease;
226
- }
227
-
228
- .sidebar .sidebar-nav .primary-nav {
229
- overflow-y: auto;
230
- scrollbar-width: thin;
231
- padding-bottom: 20px;
232
- height: calc(100vh - 227px);
233
- scrollbar-color: transparent transparent;
234
- }
235
-
236
- .sidebar .sidebar-nav .primary-nav:hover {
237
- scrollbar-color: #EEF2FF transparent;
238
- }
239
-
240
- .sidebar.collapsed .sidebar-nav .primary-nav {
241
- overflow: unset;
242
- transform: translateY(65px);
243
- }
244
-
245
- .sidebar-nav .nav-item .nav-link {
246
- color: #fff;
247
- display: flex;
248
- gap: 12px;
249
- white-space: nowrap;
250
- border-radius: 8px;
251
- padding: 11px 15px;
252
- align-items: center;
253
- text-decoration: none;
254
- border: 1px solid #151A2D;
255
- transition: 0.4s ease;
256
- }
257
-
258
- .sidebar-nav .nav-item:is(:hover, .open)>.nav-link:not(.dropdown-title) {
259
- color: #151A2D;
260
- background: #EEF2FF;
261
- }
262
-
263
- .sidebar .nav-link .nav-label {
264
- transition: opacity 0.3s ease;
265
- color: white;
266
- }
267
-
268
- .sidebar.collapsed .nav-link :where(.nav-label, .dropdown-icon) {
269
- opacity: 0;
270
- pointer-events: none;
271
- }
272
-
273
- .sidebar.collapsed .nav-link .dropdown-icon {
274
- transition: opacity 0.3s 0s ease;
275
- }
276
-
277
- .sidebar-nav .secondary-nav {
278
- position: absolute;
279
- bottom: 35px;
280
- width: 100%;
281
- background: #151A2D;
282
- }
283
-
284
- .sidebar-nav .nav-item {
285
- position: relative;
286
- }
287
-
288
-
289
- .icon-menu-arrow {
290
- font-size: 18px !important;
291
- margin-top: 1px !important;
292
- }
293
-
294
299
  .molded-icon-open {
295
300
  padding-left: 10px;
296
301
  cursor: pointer;
@@ -307,12 +312,26 @@ export default {
307
312
  background-color: white;
308
313
  }
309
314
 
315
+ .menu-active {
316
+ background-color: #D98621;
317
+ }
318
+
319
+ .module-selected {
320
+ color: #2C3453 !important;
321
+ background-color: white !important;
322
+ }
323
+
324
+ .icon-menu-arrow {
325
+ font-size: 17px;
326
+ margin-top: 7px;
327
+ }
328
+
310
329
  .molded-icon {
311
330
  cursor: pointer;
312
- margin-top: 10px;
331
+ padding: 1px;
313
332
  color: white;
314
333
  font-size: 18px;
315
- margin: 15px;
334
+ margin: 10px;
316
335
  border-radius: 10px;
317
336
  transition: all 0.3s ease;
318
337
  }
@@ -320,13 +339,12 @@ export default {
320
339
  .molded-icon:hover {
321
340
  background-color: white;
322
341
  color: #2C3453;
323
- margin: 15px;
324
- border-radius: 8px;
342
+ margin: 10px;
343
+ border-radius: 10px;
325
344
  transition: all 0.8s ease;
326
345
  }
327
346
 
328
347
  .sub {
329
- margin-top: 70px;
330
348
  cursor: pointer;
331
349
  transition: all 0.3s ease;
332
350
  }
@@ -358,9 +376,9 @@ export default {
358
376
 
359
377
  .sub-menu-collapsed {
360
378
  width: 260px;
361
- margin-top: -50px;
379
+ margin-top: -100px;
362
380
  margin-left: 85px;
363
- position: fixed;
381
+ position: absolute;
364
382
  border-radius: 0px 15px 15px 0px;
365
383
  background-color: #2C3453;
366
384
  }
@@ -415,5 +433,9 @@ export default {
415
433
  font-size: 16px;
416
434
  margin-left: 10px;
417
435
  }
418
-
436
+
437
+ .div-group {
438
+ margin-left: 10px;
439
+ padding: 5px;
440
+ }
419
441
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="panel">
2
+ <div :class="['panel', { collapsed: menuCollapsed }]">
3
3
  <Toast />
4
4
  <Loading v-show="isLoading('panel')" />
5
5
  <div v-show="!isLoading('panel')">
@@ -93,8 +93,8 @@ export default {
93
93
  this.currentRoute = this.$route.name;
94
94
  },
95
95
  computed: {
96
- ...mapGetters("generic", ["isLoading"]),
97
- ...mapState("generic", ["modal"]),
96
+ ...mapGetters("generic", ["isLoading", "event"]),
97
+ ...mapState("generic", ["modal", "menuCollapsed"]),
98
98
  },
99
99
  methods: {
100
100
  ...mapMutations("generic", ["addLoading"]),
@@ -105,10 +105,6 @@ export default {
105
105
  };
106
106
  </script>
107
107
  <style scoped>
108
- .layout-small {
109
- max-width: 1500px;
110
- }
111
-
112
108
  .local-container {
113
109
  margin: auto;
114
110
  padding-left: 100px;
@@ -147,9 +143,13 @@ export default {
147
143
  }
148
144
 
149
145
  .panel {
150
- margin-top: 30px;
151
146
  padding-right: 30px;
152
- padding-left: 20px;
147
+ margin-left: 190px;
148
+ }
149
+
150
+ .panel.collapsed {
151
+ margin-left: 10px;
152
+ transition: all 0.3s ease;
153
153
  }
154
154
 
155
155
  .div-back {
@@ -1,5 +1,9 @@
1
1
  <template>
2
2
  <div>
3
+ <div class="div-download title" @click="download">
4
+ <i class="fa-solid fa-download icon-download"></i>
5
+ <span class="title-download">Baixar</span>
6
+ </div>
3
7
  <AceEditor v-model="code" lang="html" @init="editorInit" theme="monokai" width="100%" height="400px" :options="{
4
8
  enableBasicAutocompletion: true,
5
9
  enableLiveAutocompletion: true,
@@ -11,10 +15,11 @@
11
15
  showPrintMargin: false,
12
16
  showGutter: true,
13
17
  }" />
14
- <div class="apply">
18
+ <div v-if="!editMode" class="apply">
15
19
  <b-row>
16
20
  <b-col class="text-right">
17
- <Button key="applyCode" type="primary" title="Aplicar" classIcon="far fa-code" size="small" :clicked="apply" />
21
+ <Button key="applyCode" type="primary" title="Aplicar" classIcon="far fa-code" size="small"
22
+ :clicked="apply" />
18
23
  </b-col>
19
24
  </b-row>
20
25
  </div>
@@ -25,10 +30,13 @@
25
30
  import AceEditor from "vuejs-ace-editor";
26
31
  import Button from "@nixweb/nixloc-ui/src/component/forms/Button";
27
32
 
28
- import { mapMutations } from "vuex";
33
+ import { mapMutations, mapState } from "vuex";
29
34
 
30
35
  export default {
31
36
  name: "CodeEditor",
37
+ props: {
38
+ editMode: Boolean
39
+ },
32
40
  components: {
33
41
  AceEditor,
34
42
  Button,
@@ -38,22 +46,16 @@ export default {
38
46
  code: "",
39
47
  };
40
48
  },
41
- computed: {
42
- documentHtml: {
43
- get() {
44
- return this.$store.state.generic.documentHtml;
45
- },
46
- set(value) {
47
- this.updateDocumentHtml(value);
48
- },
49
- },
50
- },
51
49
  mounted() {
52
- this.code = this.documentHtml;
50
+ this.code = this.editMode ? this.documentHtmlFinal : this.documentHtml;
51
+ },
52
+ computed: {
53
+ ...mapState("generic", ["documentHtml", "documentHtmlFinal"]),
53
54
  },
54
55
  methods: {
55
56
  ...mapMutations("generic", [
56
57
  "updateDocumentHtml",
58
+ "updateDocumentHtmlFinal",
57
59
  "hideModal",
58
60
  "removeLoading",
59
61
  ]),
@@ -70,6 +72,34 @@ export default {
70
72
  require("brace/theme/monokai");
71
73
  require("brace/snippets/javascript"); //snippet
72
74
  },
75
+ download() {
76
+ const blob = new Blob([this.code], { type: 'text/plain' });
77
+ const link = document.createElement('a');
78
+ link.href = URL.createObjectURL(blob);
79
+ link.download = 'arquivo.txt';
80
+ link.click();
81
+ URL.revokeObjectURL(link.href);
82
+ }
83
+ },
84
+ watch: {
85
+ code: {
86
+ handler(code) {
87
+ this.updateDocumentHtmlFinal(this.code);
88
+ },
89
+ deep: true,
90
+ },
91
+ documentHtml: {
92
+ handler(documentHtml) {
93
+ this.code = documentHtml;
94
+ },
95
+ deep: true,
96
+ },
97
+ documentHtmlFinal: {
98
+ handler(documentHtmlFinal) {
99
+ this.code = documentHtmlFinal;
100
+ },
101
+ deep: true,
102
+ },
73
103
  },
74
104
  };
75
105
  </script>
@@ -77,4 +107,22 @@ export default {
77
107
  .apply {
78
108
  margin-top: 10px;
79
109
  }
110
+
111
+ .div-download {
112
+ cursor: pointer;
113
+ margin-bottom: 5px;
114
+ }
115
+
116
+ .title-download {
117
+ margin-left: 6px;
118
+ font-size: 14px;
119
+ }
120
+
121
+ .title-download:hover {
122
+ text-decoration: underline;
123
+ }
124
+
125
+ .icon-download {
126
+ font-size: 18px;
127
+ }
80
128
  </style>