neo.mjs 4.0.87 → 4.0.88

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.
@@ -157,9 +157,15 @@ if (programOpts.info) {
157
157
  }
158
158
 
159
159
  if (root === 'Neo') {
160
- console.log('todo: create the file inside the src folder');
160
+ if (isDrop) {
161
+ console.log(chalk.red('Drop mode not yet supported for the neo framework scope'));
162
+ process.exit(1);
163
+ } else {
164
+ classFolder = path.join(cwd, '/src/', ns.join('/'));
165
+ folderDelta = ns.length;
166
+ }
161
167
  } else {
162
- if (isDrop === true) {
168
+ if (isDrop) {
163
169
  ns = [];
164
170
 
165
171
  let pathInfo = path.parse(cwd),
@@ -211,9 +217,7 @@ if (programOpts.info) {
211
217
  parts = delta.split(sep);
212
218
 
213
219
  folderDelta = parts.length;
214
- }
215
-
216
- if (isDrop !== true) {
220
+ } else {
217
221
  if (fs.existsSync(path.resolve(cwd, 'apps', rootLowerCase))) {
218
222
  classFolder = path.resolve(cwd, 'apps', rootLowerCase, ns.join('/'));
219
223
  } else {
@@ -221,24 +225,24 @@ if (programOpts.info) {
221
225
  process.exit(1);
222
226
  }
223
227
  }
228
+ }
224
229
 
225
- if (folderDelta === undefined) {
226
- folderDelta = ns.length + 2;
227
- }
228
-
229
- createClass({
230
- baseClass,
231
- className,
232
- isSingleton,
233
- file,
234
- folderDelta,
235
- ns,
236
- root
237
- });
230
+ if (folderDelta === undefined) {
231
+ folderDelta = ns.length + 2;
232
+ }
238
233
 
239
- if (baseClass === 'data.Model') {
240
- // todo: add a question for auto-generating a matching store
241
- }
234
+ createClass({
235
+ baseClass,
236
+ className,
237
+ isSingleton,
238
+ file,
239
+ folderDelta,
240
+ ns,
241
+ root
242
+ });
243
+
244
+ if (baseClass === 'data.Model') {
245
+ // todo: add a question for auto-generating a matching store
242
246
  }
243
247
 
244
248
  const processTime = (Math.round((new Date - startDate) * 100) / 100000).toFixed(2);
@@ -440,7 +444,7 @@ if (programOpts.info) {
440
444
  root
441
445
  } = opts, baseFileName;
442
446
 
443
- fs.mkdirpSync(classFolder);
447
+ fs.mkdirpSync(classFolder, {recursive: true});
444
448
 
445
449
  baseFileName = baseClass.split('.').pop();
446
450
 
@@ -534,7 +538,7 @@ if (programOpts.info) {
534
538
  * @param {String} opts.className
535
539
  * @param {Boolean} opts.isSingleton
536
540
  * @param {String} opts.file
537
- * @param {String} opts.folderDelta
541
+ * @param {Number} opts.folderDelta
538
542
  * @param {String} opts.ns
539
543
  * @param {String} opts.root
540
544
  * @returns {String}
@@ -544,6 +548,7 @@ if (programOpts.info) {
544
548
  baseFileName = opts.baseFileName,
545
549
  baseClassPath = baseClass.split('.').join('/'),
546
550
  className = opts.className,
551
+ importSrc = root === 'Neo' ? '' : 'src/',
547
552
  isSingleton = opts.isSingleton,
548
553
  file = opts.file,
549
554
  i = 0,
@@ -554,7 +559,7 @@ if (programOpts.info) {
554
559
  }
555
560
 
556
561
  let classContent = [
557
- `import ${baseFileName} from '${importDelta}${(insideNeo ? '' : 'node_modules/neo.mjs/')}src/${baseClassPath}.mjs';`,
562
+ `import ${baseFileName} from '${importDelta}${(insideNeo ? '' : 'node_modules/neo.mjs/')}${importSrc + baseClassPath}.mjs';`,
558
563
  "",
559
564
  "/**",
560
565
  ` * @class ${className}`,
@@ -0,0 +1,63 @@
1
+ import ConfigurationViewport from '../ConfigurationViewport.mjs';
2
+ import RangeField from '../../src/form/field/Range.mjs';
3
+ import SiteMapContainer from '../../src/sitemap/Container.mjs';
4
+
5
+ /**
6
+ * @class Neo.examples.sitemap.MainContainer
7
+ * @extends Neo.examples.ConfigurationViewport
8
+ */
9
+ class MainContainer extends ConfigurationViewport {
10
+ static getConfig() {return {
11
+ className: 'Neo.examples.sitemap.MainContainer',
12
+ autoMount: true,
13
+ layout : {ntype: 'hbox', align: 'stretch'}
14
+ }}
15
+
16
+ createConfigurationComponents() {
17
+ let me = this;
18
+
19
+ return [{
20
+ module : RangeField,
21
+ labelText : 'height',
22
+ listeners : {change: me.onConfigChange.bind(me, 'height')},
23
+ maxValue : 800,
24
+ minValue : 200,
25
+ stepSize : 1,
26
+ value : me.exampleComponent.height
27
+ }, {
28
+ module : RangeField,
29
+ labelText : 'width',
30
+ listeners : {change: me.onConfigChange.bind(me, 'width')},
31
+ maxValue : 800,
32
+ minValue : 200,
33
+ stepSize : 1,
34
+ value : me.exampleComponent.width
35
+ }]
36
+ }
37
+
38
+ createExampleComponent() {
39
+ return Neo.create(SiteMapContainer, {
40
+ height: 600,
41
+ width : 800,
42
+
43
+ itemStore: {
44
+ data: [
45
+ {id: 1, column: 0, name: 'Group 1', level: 0},
46
+ {id: 2, column: 0, name: 'Item 1', level: 1, action: 'item1'},
47
+ {id: 3, column: 0, name: 'Item 2', level: 1, action: 'item2'},
48
+ {id: 4, column: 0, name: 'Item 3', level: 2, action: 'https://github.com/neomjs/neo', actionType: 'url'},
49
+ {id: 5, column: 0, name: 'Item 4', level: 2, disabled: true},
50
+ {id: 6, column: 1, name: 'Group 2', level: 0},
51
+ {id: 7, column: 1, name: 'Item 1', level: 1},
52
+ {id: 8, column: 1, name: 'Item 2', level: 1, hidden: true},
53
+ {id: 9, column: 1, name: 'Item 3', level: 1},
54
+ {id: 10, column: 1, name: 'Item 4', level: 2}
55
+ ]
56
+ }
57
+ })
58
+ }
59
+ }
60
+
61
+ Neo.applyClassConfig(MainContainer);
62
+
63
+ export default MainContainer;
@@ -0,0 +1,6 @@
1
+ import MainContainer from './MainContainer.mjs';
2
+
3
+ export const onStart = () => Neo.app({
4
+ mainView: MainContainer,
5
+ name : 'Neo.examples.sitemap'
6
+ })
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <meta charset="UTF-8">
6
+ <title>Neo Sitemap</title>
7
+ </head>
8
+ <body>
9
+ <script src="../../src/MicroLoader.mjs" type="module"></script>
10
+ </body>
11
+ </html>
@@ -0,0 +1,6 @@
1
+ {
2
+ "appPath" : "examples/sitemap/app.mjs",
3
+ "basePath" : "../../",
4
+ "environment": "development",
5
+ "mainPath" : "./Main.mjs"
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.0.87",
3
+ "version": "4.0.88",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -27,6 +27,10 @@ html, .neo-body-viewport {
27
27
  pointer-events: none;
28
28
  }
29
29
 
30
+ .neo-hidden {
31
+ visibility: hidden;
32
+ }
33
+
30
34
  .neo-link-color {
31
35
  color: v(neo-color);
32
36
 
@@ -0,0 +1,41 @@
1
+ .neo-sitemap {
2
+ border : 1px solid v(panel-border-color);
3
+ padding: 30px 100px 60px;
4
+
5
+ .neo-action {
6
+ color : inherit;
7
+ display : block;
8
+ margin : 1em 0;
9
+ text-decoration: none;
10
+ }
11
+
12
+ .neo-action[href] {
13
+ &:hover {
14
+ text-decoration: underline;
15
+ }
16
+ }
17
+
18
+ .neo-level-0 {
19
+ font-size : 16px/22px;
20
+ font-weight: 600;
21
+ }
22
+
23
+ .neo-level-1 {
24
+ margin-left: 1em;
25
+ }
26
+
27
+ .neo-level-2 {
28
+ margin-left: 2em;
29
+ }
30
+
31
+ .neo-level-3 {
32
+ margin-left: 3em;
33
+ }
34
+
35
+ .neo-sitemap-column {
36
+ &:not(:last-child) {
37
+ border-right: 1px solid v(panel-border-color);
38
+ margin-right: 25px;
39
+ }
40
+ }
41
+ }
@@ -76,8 +76,15 @@ class RecordFactory extends Base {
76
76
 
77
77
  if (Array.isArray(model.fields)) {
78
78
  model.fields.forEach(field => {
79
- let parsedValue = instance.parseRecordValue(me, field, config[field.name], config),
80
- symbol = Symbol.for(field.name);
79
+ let value = config[field.name],
80
+ symbol = Symbol.for(field.name),
81
+ parsedValue;
82
+
83
+ if (!Object.hasOwn(config, field.name) && Object.hasOwn(field, 'defaultValue')) {
84
+ value = field.defaultValue;
85
+ }
86
+
87
+ parsedValue = instance.parseRecordValue(me, field, value, config);
81
88
 
82
89
  properties = {
83
90
  [Symbol.for('isRecord')]: {
@@ -0,0 +1,190 @@
1
+ import Base from '../container/Base.mjs';
2
+ import ClassSystemUtil from '../util/ClassSystem.mjs';
3
+ import ItemStore from './store/Items.mjs';
4
+
5
+ /**
6
+ * @class Neo.sitemap.Container
7
+ * @extends Neo.container.Base
8
+ */
9
+ class Container extends Base {
10
+ static getStaticConfig() {return {
11
+ /**
12
+ * Valid values for itemHideMode
13
+ * @member {String[]} itemHideModes=['removeDom','visibility']
14
+ * @protected
15
+ * @static
16
+ */
17
+ itemHideModes: ['removeDom', 'visibility']
18
+ }}
19
+
20
+ static getConfig() {return {
21
+ /*
22
+ * @member {String} className='Neo.sitemap.Container'
23
+ * @protected
24
+ */
25
+ className: 'Neo.sitemap.Container',
26
+ /*
27
+ * @member {String} ntype='sitemap'
28
+ * @protected
29
+ */
30
+ ntype: 'sitemap',
31
+ /*
32
+ * @member {String[} cls=['neo-sitemap','neo-container']
33
+ */
34
+ cls: ['neo-sitemap', 'neo-container'],
35
+ /*
36
+ * @member {Object} itemDefaults
37
+ */
38
+ itemDefaults: {
39
+ ntype: 'component',
40
+ cls : ['neo-sitemap-column', 'neo-container']
41
+ },
42
+ /**
43
+ * Valid values: removeDom, visibility
44
+ * Defines if the component items should use css visibility:'hidden' or vdom:removeDom
45
+ * @member {String} hideMode_='removeDom'
46
+ */
47
+ itemHideMode_: 'removeDom',
48
+ /*
49
+ * @member {Neo.sitemap.store.Items|null} itemStore_=null
50
+ */
51
+ itemStore_: null,
52
+ /**
53
+ * @member {Object} layout={ntype:'hbox',align:'stretch'}
54
+ */
55
+ layout: {ntype: 'hbox', align: 'stretch'}
56
+ }}
57
+
58
+ /**
59
+ * Triggered after the itemStore config got changed
60
+ * @param {Neo.sitemap.store.Items|null} value
61
+ * @param {Neo.sitemap.store.Items|null} oldValue
62
+ * @protected
63
+ */
64
+ afterSetItemStore(value, oldValue) {
65
+ let me = this;
66
+
67
+ value?.on({
68
+ filter : 'onItemStoreFilter',
69
+ load : 'onItemStoreLoad',
70
+ recordChange: 'onItemStoreRecordChange',
71
+ scope : me
72
+ });
73
+
74
+ value?.getCount() > 0 && me.createColumns();
75
+ }
76
+
77
+ /**
78
+ * Triggered before the itemHideMode config gets changed
79
+ * @param {String} value
80
+ * @param {String} oldValue
81
+ * @protected
82
+ */
83
+ beforeSetItemHideMode(value, oldValue) {
84
+ return this.beforeSetEnumValue(value, oldValue, 'itemHideMode');
85
+ }
86
+
87
+ /**
88
+ * Triggered before the itemStore config gets changed.
89
+ * @param {Object|Neo.data.Store} value
90
+ * @param {Object|Neo.data.Store} oldValue
91
+ * @returns {Neo.data.Store}
92
+ * @protected
93
+ */
94
+ beforeSetItemStore(value, oldValue) {
95
+ oldValue?.destroy();
96
+ return ClassSystemUtil.beforeSetInstance(value, ItemStore);
97
+ }
98
+
99
+ /**
100
+ *
101
+ */
102
+ createColumns() {
103
+ let me = this,
104
+ records = me.itemStore.items,
105
+ columnIndex = -1,
106
+ items = [],
107
+ action, column, item, record;
108
+
109
+ for (record of records) {
110
+ if (record.column !== columnIndex) {
111
+ columnIndex++;
112
+ column = {vdom: {cn: []}};
113
+ items.push(column);
114
+ }
115
+
116
+ action = record.action;
117
+
118
+ item = {
119
+ tag : 'a',
120
+ cls : ['neo-action', `neo-level-${record.level}`],
121
+ id : me.getItemId(record.id),
122
+ html: record.name
123
+ };
124
+
125
+ if (action && action !== '') {
126
+ switch (record.actionType) {
127
+ case 'handler': {
128
+ item.cls.push('neo-action-handler');
129
+ break;
130
+ }
131
+ case 'route': {
132
+ item.href = `#${record.action}`;
133
+ break;
134
+ }
135
+ case 'url': {
136
+ item.href = record.action;
137
+ item.target = '_blank';
138
+ }
139
+ }
140
+ }
141
+
142
+ record.disabled && item.cls.push('neo-disabled');
143
+
144
+ if (record.hidden) {
145
+ if (me.itemHideMode === 'removeDom') {
146
+ item.removeDom = true;
147
+ } else {
148
+ item.cls.push('neo-hidden');
149
+ }
150
+ }
151
+
152
+ column.vdom.cn.push(item);
153
+ }
154
+
155
+ me.items = items;
156
+ }
157
+
158
+ /**
159
+ * @param {Number|String} recordId
160
+ * @returns {String}
161
+ */
162
+ getItemId(recordId) {
163
+ return `${this.id}__${recordId}`;
164
+ }
165
+
166
+ /**
167
+ *
168
+ */
169
+ onItemStoreFilter() {
170
+ this.createColumns();
171
+ }
172
+
173
+ /**
174
+ *
175
+ */
176
+ onItemStoreLoad() {
177
+ this.createColumns();
178
+ }
179
+
180
+ /**
181
+ *
182
+ */
183
+ onItemStoreRecordChange() {
184
+ this.createColumns();
185
+ }
186
+ }
187
+
188
+ Neo.applyClassConfig(Container);
189
+
190
+ export default Container;
@@ -0,0 +1,51 @@
1
+ import Model from '../../data/Model.mjs';
2
+
3
+ /**
4
+ * @class Neo.sitemap.model.Item
5
+ * @extends Neo.data.Model
6
+ */
7
+ class Item extends Model {
8
+ static getConfig() {return {
9
+ /*
10
+ * @member {String} className='Neo.sitemap.model.Item'
11
+ * @protected
12
+ */
13
+ className: 'Neo.sitemap.model.Item',
14
+ /*
15
+ * @member {Object[]} fields
16
+ */
17
+ fields: [{
18
+ name: 'action',
19
+ type: 'String'
20
+ }, {
21
+ name : 'actionType',
22
+ defaultValue: 'route',
23
+ type : 'String'
24
+ }, {
25
+ name: 'column',
26
+ type: 'Number' // zero based
27
+ }, {
28
+ name : 'disabled',
29
+ defaultValue: false,
30
+ type : 'Boolean'
31
+ }, {
32
+ name : 'hidden',
33
+ defaultValue: false,
34
+ type : 'Boolean'
35
+ }, {
36
+ name: 'id',
37
+ type: 'Number'
38
+ }, {
39
+ name : 'level', // indentation
40
+ defaultValue: 0,
41
+ type : 'Number'
42
+ }, {
43
+ name: 'name',
44
+ type: 'String'
45
+ }]
46
+ }}
47
+ }
48
+
49
+ Neo.applyClassConfig(Item);
50
+
51
+ export default Item;
@@ -0,0 +1,24 @@
1
+ import ItemModel from '../model/Item.mjs';
2
+ import Store from '../../data/Store.mjs';
3
+
4
+ /**
5
+ * @class Neo.sitemap.store.Items
6
+ * @extends Neo.data.Store
7
+ */
8
+ class Items extends Store {
9
+ static getConfig() {return {
10
+ /*
11
+ * @member {String} className='Neo.sitemap.store.Items'
12
+ * @protected
13
+ */
14
+ className: 'Neo.sitemap.store.Items',
15
+ /*
16
+ * @member {Neo.data.Model} model=ItemModel
17
+ */
18
+ model: ItemModel
19
+ }}
20
+ }
21
+
22
+ Neo.applyClassConfig(Items);
23
+
24
+ export default Items;