@things-factory/menu-ui 8.0.0 → 9.0.0-beta.3

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 (56) hide show
  1. package/dist-client/apptools/favorite-tool.d.ts +28 -0
  2. package/dist-client/apptools/favorite-tool.js +139 -0
  3. package/dist-client/apptools/favorite-tool.js.map +1 -0
  4. package/dist-client/bootstrap.d.ts +4 -0
  5. package/dist-client/bootstrap.js +52 -0
  6. package/dist-client/bootstrap.js.map +1 -0
  7. package/dist-client/components/child-menus-selector.d.ts +1 -0
  8. package/dist-client/components/child-menus-selector.js +146 -0
  9. package/dist-client/components/child-menus-selector.js.map +1 -0
  10. package/dist-client/components/role-select-popup.d.ts +1 -0
  11. package/dist-client/components/role-select-popup.js +180 -0
  12. package/dist-client/components/role-select-popup.js.map +1 -0
  13. package/dist-client/index.js +2 -0
  14. package/dist-client/index.js.map +1 -0
  15. package/dist-client/pages/menu-list-page.d.ts +2 -0
  16. package/dist-client/pages/menu-list-page.js +204 -0
  17. package/dist-client/pages/menu-list-page.js.map +1 -0
  18. package/dist-client/pages/menu-management-detail.d.ts +2 -0
  19. package/dist-client/pages/menu-management-detail.js +376 -0
  20. package/dist-client/pages/menu-management-detail.js.map +1 -0
  21. package/dist-client/pages/menu-management.d.ts +3 -0
  22. package/dist-client/pages/menu-management.js +280 -0
  23. package/dist-client/pages/menu-management.js.map +1 -0
  24. package/dist-client/pages/role-menus-management.d.ts +4 -0
  25. package/dist-client/pages/role-menus-management.js +215 -0
  26. package/dist-client/pages/role-menus-management.js.map +1 -0
  27. package/dist-client/route.d.ts +1 -0
  28. package/dist-client/route.js +14 -0
  29. package/dist-client/route.js.map +1 -0
  30. package/dist-client/tsconfig.tsbuildinfo +1 -0
  31. package/dist-client/viewparts/menu-bar.d.ts +12 -0
  32. package/dist-client/viewparts/menu-bar.js +108 -0
  33. package/dist-client/viewparts/menu-bar.js.map +1 -0
  34. package/dist-client/viewparts/menu-tile-list.d.ts +13 -0
  35. package/dist-client/viewparts/menu-tile-list.js +234 -0
  36. package/dist-client/viewparts/menu-tile-list.js.map +1 -0
  37. package/dist-client/viewparts/menu-tree-bar.d.ts +28 -0
  38. package/dist-client/viewparts/menu-tree-bar.js +307 -0
  39. package/dist-client/viewparts/menu-tree-bar.js.map +1 -0
  40. package/package.json +21 -18
  41. package/things-factory.config.js +5 -14
  42. package/client/apptools/favorite-tool.js +0 -130
  43. package/client/bootstrap.js +0 -57
  44. package/client/components/child-menus-selector.js +0 -150
  45. package/client/components/role-select-popup.js +0 -179
  46. package/client/pages/menu-list-page.js +0 -200
  47. package/client/pages/menu-management-detail.js +0 -384
  48. package/client/pages/menu-management.js +0 -294
  49. package/client/pages/role-menus-management.js +0 -215
  50. package/client/route.js +0 -15
  51. package/client/viewparts/menu-bar.js +0 -114
  52. package/client/viewparts/menu-tile-list.js +0 -222
  53. package/client/viewparts/menu-tree-bar.js +0 -295
  54. package/server/index.ts +0 -0
  55. /package/{client/index.js → dist-client/index.d.ts} +0 -0
  56. /package/{client → dist-client}/themes/menu-theme.css +0 -0
@@ -1,21 +1,12 @@
1
- import route from './client/route'
2
- import bootstrap from './client/bootstrap'
1
+ import route from './dist-client/route'
2
+ import bootstrap from './dist-client/bootstrap'
3
3
 
4
4
  export default {
5
5
  route,
6
6
  routes: [
7
- {
8
- tagname: 'menu-list-page',
9
- page: 'menu-list'
10
- },
11
- {
12
- tagname: 'menu-management',
13
- page: 'menus'
14
- },
15
- {
16
- tagname: 'role-menus-management',
17
- page: 'role-menus'
18
- }
7
+ { tagname: 'menu-list-page', page: 'menu-list' },
8
+ { tagname: 'menu-management', page: 'menus' },
9
+ { tagname: 'role-menus-management', page: 'role-menus' }
19
10
  ],
20
11
  bootstrap
21
12
  }
@@ -1,130 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
-
3
- import { LitElement, html, css } from 'lit'
4
- import { connect } from 'pwa-helpers/connect-mixin.js'
5
- import gql from 'graphql-tag'
6
-
7
- import { store, client } from '@things-factory/shell'
8
- import { UPDATE_FAVORITES } from '@things-factory/fav-base'
9
-
10
- export class FavoriteTool extends connect(store)(LitElement) {
11
- static get properties() {
12
- return {
13
- favorites: Array,
14
- user: Object,
15
- page: String,
16
- resourceId: String,
17
- favored: Boolean,
18
- routingTypes: Object,
19
- blackList: Array
20
- }
21
- }
22
-
23
- static get styles() {
24
- return css`
25
- :host {
26
- display: inline-block;
27
- vertical-align: middle;
28
- line-height: 0;
29
- }
30
-
31
- [favorable] {
32
- opacity: 0.5;
33
- }
34
- `
35
- }
36
-
37
- render() {
38
- var renderable = (this.blackList || []).indexOf(this.page) == -1
39
-
40
- return renderable
41
- ? html`
42
- <md-icon @click=${this.onclick.bind(this)} ?favorable=${!this.favored}
43
- >${this.favored ? 'star' : 'star_border'}</md-icon
44
- >
45
- `
46
- : html``
47
- }
48
-
49
- updated(changes) {
50
- if (changes.has('user')) {
51
- this.refreshFavorites()
52
- }
53
-
54
- this.favored = (this.favorites || []).includes(this.getFullRouting())
55
- }
56
-
57
- stateChanged(state) {
58
- this.favorites = state.favorite.favorites
59
- this.user = state.auth.user
60
- this.page = state.route.page
61
- this.resourceId = state.route.resourceId
62
- this.routingTypes = state.menu.routingTypes
63
- }
64
-
65
- onclick(event) {
66
- if (this.favored) {
67
- this.removeFavorite(this.getFullRouting())
68
- } else {
69
- this.addFavorite(this.getFullRouting())
70
- }
71
- }
72
-
73
- async refreshFavorites() {
74
- if (!this.user || !this.user.email) {
75
- return
76
- }
77
-
78
- const response = await client.query({
79
- query: gql`
80
- query {
81
- myFavorites {
82
- id
83
- routing
84
- }
85
- }
86
- `
87
- })
88
-
89
- store.dispatch({
90
- type: UPDATE_FAVORITES,
91
- favorites: response.data.myFavorites.map(favorite => favorite.routing)
92
- })
93
- }
94
-
95
- async removeFavorite(routing) {
96
- await client.query({
97
- query: gql`
98
- mutation {
99
- deleteFavorite(routing: "${routing}")
100
- }
101
- `
102
- })
103
-
104
- this.refreshFavorites()
105
- }
106
-
107
- async addFavorite(routing) {
108
- await client.query({
109
- query: gql`
110
- mutation {
111
- createFavorite(favorite: {
112
- routing: "${routing}"
113
- }) {
114
- id
115
- routing
116
- }
117
- }
118
- `
119
- })
120
-
121
- this.refreshFavorites()
122
- }
123
-
124
- getFullRouting() {
125
- var routingType = Object.values(this.routingTypes).find(type => type.page == this.page)
126
- return routingType ? `${this.page}/${this.resourceId}` : this.page
127
- }
128
- }
129
-
130
- customElements.define('favorite-tool', FavoriteTool)
@@ -1,57 +0,0 @@
1
- import '@operato/i18n'
2
- import './apptools/favorite-tool'
3
- import './viewparts/menu-tree-bar'
4
-
5
- import { html } from 'lit-html'
6
-
7
- import { appendViewpart, TOOL_POSITION, VIEWPART_POSITION } from '@operato/layout'
8
- import { APPEND_APP_TOOL } from '@things-factory/apptool-base/client'
9
- import { auth } from '@things-factory/auth-base/dist-client'
10
- import { ADD_MORENDA } from '@things-factory/more-base/client'
11
- import { navigate, store } from '@operato/shell'
12
- import { isMobileDevice } from '@operato/utils'
13
-
14
- export default function bootstrap() {
15
- if (!isMobileDevice()) {
16
- appendViewpart({
17
- name: 'menu-tree-bar',
18
- viewpart: {
19
- show: true,
20
- template: html` <menu-tree-bar></menu-tree-bar> `
21
- },
22
- position: VIEWPART_POSITION.NAVBAR
23
- })
24
- }
25
-
26
- store.dispatch({
27
- type: APPEND_APP_TOOL,
28
- tool: {
29
- name: 'favorite-tool',
30
- template: html` <favorite-tool .blackList=${['menu-list']}></favorite-tool> `,
31
- position: TOOL_POSITION.REAR
32
- }
33
- })
34
-
35
- auth.on('profile', ({ credential }) => {
36
- if (credential.owner) {
37
- appendRoleMenusManagementMorenda()
38
- }
39
- })
40
- }
41
-
42
- function appendRoleMenusManagementMorenda() {
43
- const useRoleByMenusManagementMenu = store.getState()?.menu?.useRoleByMenusManagementMenu || false
44
-
45
- if (useRoleByMenusManagementMenu) {
46
- store.dispatch({
47
- type: ADD_MORENDA,
48
- morenda: {
49
- icon: html` <md-icon>menu</md-icon> `,
50
- name: html` <ox-i18n msgid="title.role_menus_management"></ox-i18n> `,
51
- action: () => {
52
- navigate('role-menus')
53
- }
54
- }
55
- })
56
- }
57
- }
@@ -1,150 +0,0 @@
1
- import { i18next, localize } from '@operato/i18n'
2
- import { client } from '@operato/graphql'
3
- import gql from 'graphql-tag'
4
- import { css, html, LitElement } from 'lit'
5
-
6
- class ChildMenusSelector extends localize(i18next)(LitElement) {
7
- static get styles() {
8
- return [
9
- css`
10
- :host {
11
- display: flex;
12
- flex-direction: column;
13
- border: 1px solid var(--md-sys-color-primary);
14
- font: normal 15px var(--theme-font);
15
- color: var(--md-sys-color-secondary);
16
- }
17
- div {
18
- margin: var(--spacing-medium);
19
- }
20
- ul {
21
- flex: 1;
22
- background-color: var(--md-sys-color-surface);
23
- overflow: auto;
24
- display: grid;
25
- grid-template-columns: 1fr 1fr;
26
- margin: 0;
27
- padding: var(--spacing-medium);
28
- list-style: none;
29
- border: 1px dashed rgba(0, 0, 0, 0.1);
30
- border-width: 1px 0;
31
- }
32
-
33
- input[type='checkbox'] {
34
- display: inline;
35
- }
36
-
37
- li {
38
- padding: var(--spacing-small);
39
- }
40
-
41
- #checkAll,
42
- [for='checkAll'] {
43
- margin-bottom: var(--spacing-medium);
44
- padding-bottom: var(--spacing-small);
45
- font-weight: bold;
46
- }
47
-
48
- @media screen and (max-width: 480px) {
49
- ul {
50
- grid-template-columns: 1fr;
51
- }
52
- }
53
- `
54
- ]
55
- }
56
-
57
- static get properties() {
58
- return {
59
- parentMenu: Object,
60
- roleMenus: Array,
61
- targetRole: Object
62
- }
63
- }
64
-
65
- render() {
66
- const parentMenu = this.parentMenu || {}
67
- const menus = parentMenu.children || []
68
- const roleMenus = this.roleMenus || []
69
-
70
- return html`
71
- <div>
72
- <input id="checkAll" type="checkbox" @change=${e => this.onCheckAll(e)} />
73
- <label for="checkAll">Check all</label>
74
- </div>
75
-
76
- <ul menus>
77
- ${menus?.map(
78
- menu => html`
79
- <li>
80
- <label for="${menu.id}"
81
- >${menu.name}
82
- <input
83
- type="checkbox"
84
- id="${menu.id}"
85
- .checked=${roleMenus.map(p => p.id).indexOf(menu.id) > -1}
86
- .data-menu=${menu.id}
87
- @change=${e => this.onSave(e)}
88
- />
89
- </label>
90
- </li>
91
- `
92
- )}
93
- </ul>
94
- `
95
- }
96
-
97
- get menuList() {
98
- return this.renderRoot.querySelectorAll('ul[menus] input[type=checkbox]')
99
- }
100
-
101
- async onCheckAll(e) {
102
- const checked = e.currentTarget.checked
103
-
104
- Array.from(this.menuList).forEach(checkbox => (checkbox.checked = checked))
105
-
106
- const response = await client.mutate({
107
- mutation: gql`
108
- mutation ($roleId: String!, $parentMenuId: String!, $isCheckedAll: Boolean!) {
109
- updateRoleMenus(roleId: $roleId, parentMenuId: $parentMenuId, isCheckedAll: $isCheckedAll) {
110
- name
111
- }
112
- }
113
- `,
114
- variables: { roleId: this.targetRole.id, parentMenuId: this.parentMenu.id, isCheckedAll: checked }
115
- })
116
-
117
- if (!response.errors) {
118
- this.dispatchEvent(new CustomEvent('updateRoleMenus'))
119
- this.showToast(i18next.t('text.data_updated_successfully'))
120
- }
121
- }
122
-
123
- async onSave(e) {
124
- const menuId = e.currentTarget.id
125
- const isCheckedMenu = e.currentTarget.checked
126
-
127
- const response = await client.mutate({
128
- mutation: gql`
129
- mutation ($roleId: String!, $targetMenuId: String!, $isCheckedMenu: Boolean!) {
130
- updateRoleMenu(roleId: $roleId, targetMenuId: $targetMenuId, isCheckedMenu: $isCheckedMenu) {
131
- id
132
- name
133
- }
134
- }
135
- `,
136
- variables: { roleId: this.targetRole.id, targetMenuId: menuId, isCheckedMenu }
137
- })
138
-
139
- if (!response.errors) {
140
- this.dispatchEvent(new CustomEvent('updateRoleMenus'))
141
- this.showToast(i18next.t('text.data_updated_successfully'))
142
- }
143
- }
144
-
145
- showToast(message) {
146
- document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
147
- }
148
- }
149
-
150
- customElements.define('child-menus-selector', ChildMenusSelector)
@@ -1,179 +0,0 @@
1
- import { i18next, localize } from '@operato/i18n'
2
- import { client } from '@operato/graphql'
3
- import gql from 'graphql-tag'
4
- import { css, html, LitElement } from 'lit'
5
- import { isMobileDevice } from '@operato/utils'
6
- import '@operato/data-grist'
7
- import { CommonHeaderStyles } from '@operato/styles'
8
-
9
- class RoleSelectPopup extends localize(i18next)(LitElement) {
10
- static get styles() {
11
- return [
12
- CommonHeaderStyles,
13
- css`
14
- :host {
15
- display: flex;
16
- flex-direction: column;
17
- overflow: hidden;
18
- background-color: var(--md-sys-color-surface);
19
- }
20
-
21
- .container {
22
- flex: 1;
23
- display: flex;
24
- overflow-y: auto;
25
- min-height: 20vh;
26
- }
27
-
28
- .grist {
29
- display: flex;
30
- flex-direction: column;
31
- flex: 1;
32
- overflow-y: auto;
33
- }
34
-
35
- ox-grist {
36
- overflow-y: hidden;
37
- flex: 1;
38
- }
39
- `
40
- ]
41
- }
42
-
43
- static get properties() {
44
- return {
45
- _searchFields: Array,
46
- config: Object
47
- }
48
- }
49
-
50
- render() {
51
- return html`
52
- <search-form .fields=${this._searchFields} @submit=${async () => this.dataGrist.fetch()}></search-form>
53
-
54
- <div class="container">
55
- <div class="grist">
56
- <ox-grist
57
- .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
58
- .config=${this.config}
59
- .fetchHandler="${this.fetchHandler.bind(this)}"
60
- ></ox-grist>
61
- </div>
62
- </div>
63
-
64
- <div class="footer">
65
- <div filler></div>
66
- <button @click=${this._selectRole.bind(this)} label=${i18next.t('button.select')} done></button>
67
- </div>
68
- `
69
- }
70
-
71
- get searchForm() {
72
- return this.shadowRoot.querySelector('search-form')
73
- }
74
-
75
- get dataGrist() {
76
- return this.shadowRoot.querySelector('ox-grist')
77
- }
78
-
79
- firstUpdated() {
80
- this._searchFields = [
81
- {
82
- name: 'name',
83
- type: 'text',
84
- props: {
85
- placeholder: i18next.t('field.name'),
86
- searchOper: 'i_like'
87
- }
88
- },
89
- {
90
- name: 'description',
91
- type: 'text',
92
- props: {
93
- placeholder: i18next.t('field.description'),
94
- searchOper: 'i_like'
95
- }
96
- }
97
- ]
98
-
99
- this.config = {
100
- rows: {
101
- appendable: false
102
- },
103
- columns: [
104
- { type: 'gutter', gutterName: 'sequence' },
105
- { type: 'gutter', gutterName: 'row-selector', multiple: false },
106
- {
107
- type: 'string',
108
- name: 'name',
109
- header: i18next.t('field.name'),
110
- record: {
111
- editable: false
112
- },
113
- width: 200
114
- },
115
- {
116
- type: 'string',
117
- name: 'description',
118
- header: i18next.t('field.description'),
119
- record: {
120
- editable: true
121
- },
122
- width: 250
123
- },
124
- {
125
- type: 'datetime',
126
- name: 'updatedAt',
127
- header: i18next.t('field.updated_at'),
128
- width: 180
129
- }
130
- ]
131
- }
132
- }
133
-
134
- async fetchHandler({ page, limit, sorters = [] }) {
135
- const filters = this.searchForm?.queryFilters || []
136
-
137
- const response = await client.query({
138
- query: gql`
139
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
140
- roles(filters: $filters, pagination: $pagination, sortings: $sortings) {
141
- items {
142
- id
143
- name
144
- description
145
- updatedAt
146
- }
147
- total
148
- }
149
- }
150
- `,
151
- variables: {
152
- filters,
153
- pagination: { page, limit },
154
- sortings: sorters
155
- }
156
- })
157
-
158
- return {
159
- total: response.data.roles.total || 0,
160
- records: response.data.roles.items || []
161
- }
162
- }
163
-
164
- _selectRole() {
165
- const selectedRole = this.dataGrist.selected[0]
166
- if (selectedRole) {
167
- this.dispatchEvent(new CustomEvent('selected', { detail: this.dataGrist.selected[0] }))
168
- history.back()
169
- } else {
170
- this.showToast(i18next.t('text.target_is_not_selected'))
171
- }
172
- }
173
-
174
- showToast(message) {
175
- document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
176
- }
177
- }
178
-
179
- window.customElements.define('role-select-popup', RoleSelectPopup)