@enso-ui/ui 6.2.7 → 7.0.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 (66) hide show
  1. package/LICENSE +1 -1
  2. package/bulma/index.js +2 -2
  3. package/package.json +34 -31
  4. package/renderless/index.js +2 -2
  5. package/src/bulma/components/AppFooter.vue +11 -11
  6. package/src/bulma/components/Breadcrumbs.vue +32 -5
  7. package/src/bulma/components/VueAside.vue +7 -11
  8. package/src/bulma/components/menu/Sidebar.vue +26 -10
  9. package/src/bulma/components/navbar/AppUpdate.vue +38 -14
  10. package/src/bulma/components/navbar/Navbar.vue +17 -15
  11. package/src/bulma/components/navbar/NavbarItem.vue +2 -4
  12. package/src/bulma/components/navbar/Search.vue +6 -5
  13. package/src/bulma/components/navbar/SettingsControl.vue +6 -5
  14. package/src/bulma/components/settings/Settings.vue +17 -3
  15. package/src/bulma/components/settings/SidebarState.vue +1 -2
  16. package/src/bulma/layouts/Default.vue +8 -22
  17. package/src/bulma/pages/MaintenanceMode.vue +5 -7
  18. package/src/bulma/pages/NotFound.vue +6 -5
  19. package/src/bulma/pages/Unauthorized.vue +5 -4
  20. package/src/bulma/styles/components/form.scss +151 -0
  21. package/src/bulma/styles/components/tables.scss +695 -0
  22. package/src/bulma/styles/components/vue-filter.scss +173 -0
  23. package/src/bulma/styles/components.sass +3 -0
  24. package/src/core/Root.vue +26 -7
  25. package/src/core/app.js +1 -1
  26. package/src/core/components/AppFooter.vue +2 -6
  27. package/src/core/components/DocumentTitle.vue +8 -3
  28. package/src/core/components/PageHeader.vue +7 -3
  29. package/src/core/components/menu/Sidebar.vue +2 -6
  30. package/src/core/components/navbar/Navbar.vue +17 -19
  31. package/src/core/components/navbar/Search.vue +10 -3
  32. package/src/core/components/navbar/SettingsControl.vue +4 -2
  33. package/src/core/components/settings/Settings.vue +6 -20
  34. package/src/core/components/settings/SidebarState.vue +5 -7
  35. package/src/core/layouts/Default.vue +96 -65
  36. package/src/core/layouts/Home.vue +27 -28
  37. package/src/core/services/contexts.js +51 -11
  38. package/src/core/services/errorHandler.js +4 -4
  39. package/src/core/services/pinia.js +7 -0
  40. package/src/core/services/resources.js +22 -17
  41. package/src/core/services/router.js +2 -3
  42. package/src/icons.js +8 -2
  43. package/src/middleware/before/auth.js +9 -5
  44. package/src/middleware/before/guest.js +6 -2
  45. package/src/middleware/before.js +5 -4
  46. package/src/modules/importers/routeImporter.js +23 -0
  47. package/src/modules/plugins/bootEnums.js +10 -1
  48. package/src/modules/plugins/date-fns/format.js +11 -6
  49. package/src/modules/plugins/date-fns/formatDistance.js +2 -2
  50. package/src/modules/plugins/i18n.js +7 -5
  51. package/src/modules/plugins/route.js +3 -3
  52. package/src/pinia/app.js +75 -0
  53. package/src/pinia/layout.js +115 -0
  54. package/src/pinia/loadState.js +78 -0
  55. package/src/pinia/preferences.js +90 -0
  56. package/src/pinia/websockets.js +48 -0
  57. package/src/core/services/store.js +0 -26
  58. package/src/modules/importers/storeImporter.js +0 -8
  59. package/src/modules/importers/themeImporter.js +0 -5
  60. package/src/modules/store/layout/navbar.js +0 -8
  61. package/src/modules/store/layout/settings.js +0 -7
  62. package/src/modules/store/layout/sidebar.js +0 -22
  63. package/src/modules/store/layout.js +0 -72
  64. package/src/modules/store/preferences.js +0 -80
  65. package/src/modules/store/websockets.js +0 -39
  66. package/src/modules/store.js +0 -115
@@ -0,0 +1,173 @@
1
+ :is(.vue-filter, .input-filter, .interval-filter, .date-filter) {
2
+ background-color: var(--enso-filter-surface);
3
+ border: 1px solid var(--enso-surface-border);
4
+
5
+ :is(.header, .filter-header, .tabs-wrapper, .input-wrapper, .filter-wrapper, .select-wrapper, .filter-surface) {
6
+ background-color: var(--enso-filter-surface);
7
+ color: var(--bulma-text-strong);
8
+ }
9
+
10
+ :is(.header, .filter-header) {
11
+ border-top-left-radius: inherit;
12
+ border-top-right-radius: inherit;
13
+ border-bottom: 1px solid color-mix(in srgb, var(--enso-surface-border) 70%, transparent);
14
+ padding-top: 0.5rem;
15
+ }
16
+
17
+ :is(.tabs-wrapper, .input-wrapper, .filter-wrapper, .select-wrapper) {
18
+ border-radius: inherit;
19
+ padding: 0.25em;
20
+ }
21
+
22
+ :is(.tabs, .filter-tags) {
23
+ background-color: var(--enso-filter-control-surface);
24
+ border: 1px solid var(--enso-surface-border);
25
+ box-shadow: none;
26
+ }
27
+
28
+ :is(.input, .textarea, .flatpickr-input.input),
29
+ .select select {
30
+ background-color: var(--enso-filter-control-surface);
31
+ }
32
+
33
+ .control.has-icons-right .icon.clear-button {
34
+ pointer-events: all;
35
+ }
36
+
37
+ .select-wrapper {
38
+ --enso-select-trigger-radius: var(--bulma-radius);
39
+ --enso-select-dropdown-radius: var(--bulma-radius);
40
+ }
41
+
42
+ .vue-select {
43
+ --enso-select-trigger-surface: var(--enso-filter-control-surface);
44
+ --enso-select-trigger-border: var(--enso-surface-border);
45
+ --enso-select-trigger-color: var(--bulma-text-strong);
46
+ }
47
+ }
48
+
49
+ .vue-filter,
50
+ .toggle-filter {
51
+ .tabs-wrapper .tabs {
52
+ --enso-filter-accent: var(--bulma-warning);
53
+ min-height: var(--bulma-control-height);
54
+ height: var(--bulma-control-height);
55
+ border-radius: var(--bulma-radius);
56
+ -ms-overflow-style: none;
57
+ overflow: -moz-scrollbars-none;
58
+
59
+ &::-webkit-scrollbar {
60
+ display: none;
61
+ }
62
+
63
+ li {
64
+ a {
65
+ min-height: var(--bulma-control-height);
66
+ height: var(--bulma-control-height);
67
+ padding: 0 0.25rem;
68
+ }
69
+
70
+ a:hover {
71
+ border-color: color-mix(in srgb, var(--enso-surface-border) 78%, transparent);
72
+ color: var(--bulma-text-strong);
73
+ }
74
+
75
+ &.is-active a {
76
+ background-color: var(--enso-filter-active-surface);
77
+ border-color: var(--enso-filter-active-border);
78
+ color: var(--enso-filter-active-color);
79
+ }
80
+ }
81
+
82
+ ul,
83
+ li:first-child a {
84
+ border-top-left-radius: var(--bulma-radius);
85
+ border-bottom-left-radius: var(--bulma-radius);
86
+ }
87
+
88
+ li:last-child a {
89
+ border-top-right-radius: var(--bulma-radius);
90
+ border-bottom-right-radius: var(--bulma-radius);
91
+ }
92
+ }
93
+ }
94
+
95
+ .vue-filter {
96
+ &.is-primary { --enso-filter-accent: var(--bulma-primary); }
97
+ &.is-link { --enso-filter-accent: var(--bulma-link); }
98
+ &.is-info { --enso-filter-accent: var(--bulma-info); }
99
+ &.is-success { --enso-filter-accent: var(--bulma-success); }
100
+ &.is-warning { --enso-filter-accent: var(--bulma-warning); }
101
+ &.is-danger { --enso-filter-accent: var(--bulma-danger); }
102
+
103
+ .tabs.is-toggle li a {
104
+ background-color: transparent;
105
+ border-color: transparent;
106
+ color: var(--bulma-text);
107
+ box-shadow: none;
108
+ }
109
+ }
110
+
111
+ .input-filter,
112
+ .interval-filter {
113
+ .input-wrapper .input.control {
114
+ border-radius: var(--bulma-radius);
115
+ }
116
+ }
117
+
118
+ .date-filter {
119
+ .tag {
120
+ cursor: pointer;
121
+ margin: 2px;
122
+ }
123
+
124
+ .tags-wrapper .filter-tags {
125
+ display: flex;
126
+ align-items: center;
127
+ justify-content: center;
128
+ flex-wrap: wrap;
129
+ gap: 0.125rem;
130
+ min-height: var(--bulma-control-height);
131
+ height: var(--bulma-control-height);
132
+ padding: 0 0.2rem;
133
+ border-radius: var(--bulma-radius);
134
+
135
+ .direction-wrapper {
136
+ display: inline-flex;
137
+ align-items: center;
138
+ min-height: var(--bulma-control-height);
139
+ height: var(--bulma-control-height);
140
+ }
141
+
142
+ .direction {
143
+ display: flex;
144
+ align-items: center;
145
+ }
146
+ }
147
+
148
+ .filter-wrapper {
149
+ .flatpickr-input,
150
+ .input,
151
+ .control .input {
152
+ border-radius: var(--bulma-radius);
153
+ }
154
+ }
155
+
156
+ .filter-tags .tag {
157
+ background-color: transparent;
158
+ border: 1px solid transparent;
159
+ color: var(--bulma-text);
160
+ box-shadow: none;
161
+ }
162
+
163
+ .filter-tags .tag:hover {
164
+ border-color: color-mix(in srgb, var(--enso-surface-border) 78%, transparent);
165
+ color: var(--bulma-text-strong);
166
+ }
167
+
168
+ .filter-tags .tag.is-warning {
169
+ background-color: var(--enso-filter-active-surface);
170
+ border-color: var(--enso-filter-active-border);
171
+ color: var(--enso-filter-active-color);
172
+ }
173
+ }
@@ -0,0 +1,3 @@
1
+ @use "./components/form"
2
+ @use "./components/tables"
3
+ @use "./components/vue-filter"
package/src/core/Root.vue CHANGED
@@ -1,11 +1,13 @@
1
1
  <script>
2
- import { mapState, mapActions, mapGetters } from 'vuex';
3
2
  import { isNavigationFailure } from 'vue-router';
4
3
  import RouteMapper from '@enso-ui/route-mapper';
5
4
  import toastr from '@enso-ui/toastr';
6
5
  import http from 'axios';
7
6
  import i18n from '../modules/plugins/i18n';
8
7
  import ErrorHandler from './services/errorHandler';
8
+ import { useStore } from './services/pinia';
9
+ import { app } from '../pinia/app';
10
+ import { layout } from '../pinia/layout';
9
11
 
10
12
  http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
11
13
 
@@ -33,11 +35,26 @@ export default {
33
35
  }),
34
36
 
35
37
  computed: {
36
- ...mapState(['meta', 'routes']),
37
- ...mapState('auth', ['isAuth']),
38
- ...mapState('layout', ['home']),
39
- ...mapGetters({ routeCollection: 'routes' }),
40
- ...mapGetters('localisation', ['rtl']),
38
+ meta() {
39
+ return app().meta;
40
+ },
41
+ routes() {
42
+ return app().routes;
43
+ },
44
+ isAuth() {
45
+ return useStore('auth')?.isAuth ?? false;
46
+ },
47
+ home() {
48
+ return layout().home;
49
+ },
50
+ routeCollection() {
51
+ return Object.keys(this.routes);
52
+ },
53
+ rtl() {
54
+ const localisation = useStore('localisation');
55
+
56
+ return localisation?.rtl ?? false;
57
+ },
41
58
  direction() {
42
59
  return this.rtl ? 'rtl' : 'ltr';
43
60
  },
@@ -62,7 +79,9 @@ export default {
62
79
  },
63
80
 
64
81
  methods: {
65
- ...mapActions('layout', ['loadTheme']),
82
+ loadTheme() {
83
+ return layout().loadTheme();
84
+ },
66
85
  canAccess(route) {
67
86
  return this.routeCollection.includes(route);
68
87
  },
package/src/core/app.js CHANGED
@@ -13,7 +13,7 @@ class App {
13
13
  this.instance = app;
14
14
  this.store = store;
15
15
  this.router = router;
16
- Resources.boot();
16
+ Resources.boot(this);
17
17
  }
18
18
 
19
19
  registerNavbarItem(key, component, order, permission = null) {
@@ -1,16 +1,12 @@
1
1
  <script>
2
- import { mapState } from 'vuex';
2
+ import { app } from '../../pinia/app';
3
3
 
4
4
  export default {
5
5
  name: 'AppFooter',
6
6
 
7
- computed: {
8
- ...mapState(['meta']),
9
- },
10
-
11
7
  render() {
12
8
  return this.$slots.default({
13
- meta: this.meta,
9
+ meta: app().meta,
14
10
  });
15
11
  },
16
12
  };
@@ -1,5 +1,6 @@
1
1
  <script>
2
- import { mapState, mapGetters } from 'vuex';
2
+ import { app } from '../../pinia/app';
3
+ import { preferences } from '../../pinia/preferences';
3
4
 
4
5
  export default {
5
6
  name: 'DocumentTitle',
@@ -7,8 +8,12 @@ export default {
7
8
  inject: ['i18n'],
8
9
 
9
10
  computed: {
10
- ...mapState(['meta']),
11
- ...mapGetters('preferences', ['lang']),
11
+ meta() {
12
+ return app().meta;
13
+ },
14
+ lang() {
15
+ return preferences().global.lang;
16
+ },
12
17
  documentTitle() {
13
18
  if (this.$route.name === 'notFound') {
14
19
  return '';
@@ -1,11 +1,13 @@
1
1
  <script>
2
- import { mapState, mapMutations } from 'vuex';
2
+ import { app } from '../../pinia/app';
3
3
 
4
4
  export default {
5
5
  name: 'PageHeader',
6
6
 
7
7
  computed: {
8
- ...mapState(['meta']),
8
+ meta() {
9
+ return app().meta;
10
+ },
9
11
  },
10
12
 
11
13
  created() {
@@ -15,7 +17,9 @@ export default {
15
17
  },
16
18
 
17
19
  methods: {
18
- ...mapMutations(['setPageTitle']),
20
+ setPageTitle(title) {
21
+ app().setPageTitle(title);
22
+ },
19
23
  },
20
24
 
21
25
  render() {
@@ -1,16 +1,12 @@
1
1
  <script>
2
- import { mapState } from 'vuex';
2
+ import { useStore } from '../../services/pinia';
3
3
 
4
4
  export default {
5
5
  name: 'Sidebar',
6
6
 
7
- computed: {
8
- ...mapState('menu', ['menus']),
9
- },
10
-
11
7
  render() {
12
8
  return this.$slots.default({
13
- menus: this.menus,
9
+ menus: useStore('menu')?.menus ?? [],
14
10
  });
15
11
  },
16
12
  };
@@ -1,7 +1,8 @@
1
1
  <script>
2
- import { mapState, mapGetters, mapMutations } from 'vuex';
3
2
  import App from '../../app';
4
3
  import eventBus from '../../services/eventBus';
4
+ import { app as useApp } from '../../pinia/app';
5
+ import { layout as useLayout } from '../../pinia/layout';
5
6
 
6
7
  export default {
7
8
  name: 'Navbar',
@@ -10,33 +11,30 @@ export default {
10
11
 
11
12
  emits: ['stop-impersonating'],
12
13
 
13
- computed: {
14
- ...mapState(['meta', 'impersonating']),
15
- ...mapState('layout', ['isMobile', 'isTouch', 'sidebar']),
16
- ...mapGetters(['routes']),
17
- items() {
18
- return App.navbarItems.sort((a, b) => a.order - b.order)
19
- .filter(({ permission }) => !permission
20
- || this.routes.includes(permission));
21
- },
22
- },
23
-
24
14
  methods: {
25
- ...mapMutations('layout/sidebar', { toggleSidebar: 'toggle' }),
15
+ toggleSidebar() {
16
+ useLayout().toggleSidebar();
17
+ },
26
18
  stopImpersonating() {
27
19
  eventBus.$emit('stop-impersonating');
28
20
  },
29
21
  },
30
22
 
31
23
  render() {
24
+ const app = useApp();
25
+ const layout = useLayout();
26
+ const routes = Object.keys(app.routes);
27
+ const items = App.navbarItems.sort((a, b) => a.order - b.order)
28
+ .filter(({ permission }) => !permission || routes.includes(permission));
29
+
32
30
  return this.$slots.default({
33
- meta: this.meta,
34
- impersonating: this.impersonating,
31
+ meta: app.meta,
32
+ impersonating: app.impersonating,
35
33
  stopImpersonating: this.stopImpersonating,
36
- isMobile: this.isMobile,
37
- isTouch: this.isTouch,
38
- sidebar: this.sidebar,
39
- items: this.items,
34
+ isMobile: layout.isMobile,
35
+ isTouch: layout.isTouch,
36
+ sidebar: layout.sidebar,
37
+ items,
40
38
  toggleSidebar: this.toggleSidebar,
41
39
  });
42
40
  },
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { mapState, mapMutations } from 'vuex';
2
+ import { layout } from '../../pinia/layout';
3
3
 
4
4
  export default {
5
5
  name: 'Search',
@@ -22,7 +22,9 @@ export default {
22
22
  }),
23
23
 
24
24
  computed: {
25
- ...mapState('layout/navbar', ['isVisible']),
25
+ isVisible() {
26
+ return layout().navbar.isVisible;
27
+ },
26
28
  },
27
29
 
28
30
  mounted() {
@@ -34,7 +36,12 @@ export default {
34
36
  },
35
37
 
36
38
  methods: {
37
- ...mapMutations('layout/navbar', ['show', 'hide']),
39
+ show() {
40
+ layout().showNavbar();
41
+ },
42
+ hide() {
43
+ layout().hideNavbar();
44
+ },
38
45
  redirect(item, to = null) {
39
46
  if (!to && !item.routes.length) {
40
47
  return;
@@ -1,11 +1,13 @@
1
1
  <script>
2
- import { mapMutations } from 'vuex';
2
+ import { layout } from '../../pinia/layout';
3
3
 
4
4
  export default {
5
5
  name: 'SettingsControl',
6
6
 
7
7
  methods: {
8
- ...mapMutations('layout/settings', ['toggle']),
8
+ toggle() {
9
+ layout().toggleSettings();
10
+ },
9
11
  },
10
12
 
11
13
  render() {
@@ -1,31 +1,17 @@
1
1
  <script>
2
- import { mapState, mapGetters } from 'vuex';
3
2
  import App from '../../app';
3
+ import { app } from '../../pinia/app';
4
4
 
5
5
  export default {
6
6
  name: 'Settings',
7
7
 
8
- computed: {
9
- ...mapState(['user']),
10
- ...mapState(['meta']),
11
- ...mapState('layout', ['themes']),
12
- ...mapState('localisation', ['languages']),
13
- ...mapGetters(['routes']),
14
- multiTheme() {
15
- return Object.keys(this.themes).length > 1;
16
- },
17
- items() {
18
- return App.settingsItems.sort((a, b) => a.order - b.order)
19
- .filter(({ permission }) => !permission
20
- || this.routes.includes(permission));;
21
- },
22
- },
23
-
24
8
  render() {
9
+ const routes = Object.keys(app().routes);
10
+ const items = [...App.settingsItems].sort((a, b) => a.order - b.order)
11
+ .filter(({ permission }) => !permission || routes.includes(permission));
12
+
25
13
  return this.$slots.default({
26
- multiTheme: this.multiTheme,
27
- meta: this.meta,
28
- items: this.items,
14
+ items,
29
15
  });
30
16
  },
31
17
  };
@@ -1,21 +1,19 @@
1
1
  <script>
2
- import { mapGetters, mapActions } from 'vuex';
2
+ import { preferences } from '../../pinia/preferences';
3
3
 
4
4
  export default {
5
5
  name: 'SidebarState',
6
6
 
7
- computed: {
8
- ...mapGetters('preferences', ['expandedSidebar']),
9
- },
10
-
11
7
  methods: {
12
- ...mapActions('preferences', ['setSidebarState']),
8
+ setSidebarState(state) {
9
+ return preferences().setSidebarState(state);
10
+ },
13
11
  },
14
12
 
15
13
  render() {
16
14
  return this.$slots.default({
17
15
  bindings: {
18
- modelValue: this.expandedSidebar,
16
+ modelValue: preferences().global.expandedSidebar,
19
17
  },
20
18
  events: {
21
19
  'update:modelValue': state => (this.setSidebarState(state)),