goblin-desktop 2.0.0 → 2.0.7

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.
@@ -30,6 +30,7 @@ module.exports = (config) => {
30
30
  const {
31
31
  name,
32
32
  title,
33
+ skills,
33
34
  dialog,
34
35
  steps,
35
36
  gadgets,
@@ -120,81 +121,81 @@ module.exports = (config) => {
120
121
  },
121
122
  };
122
123
 
123
- Goblin.registerQuest(goblinName, 'create', function* (
124
- quest,
125
- desktopId,
126
- form,
127
- isDialog
128
- ) {
129
- const id = quest.goblin.id;
130
- quest.goblin.setX('desktopId', desktopId);
131
- quest.goblin.setX('isDialog', isDialog);
132
- quest.goblin.setX('isDisposing', false);
133
- const wizardGadgets = {};
134
-
135
- if (gadgets) {
136
- for (const key of Object.keys(gadgets)) {
137
- const gadget = gadgets[key];
138
- // const newGadgetId = `${gadget.type}@${quest.goblin.id}`;
139
- const newGadgetId = `${key}@${quest.goblin.id}`; // Uses 'key' instead of 'gadget.type' to allow the same gadget to be used in a wizard more than once.
140
- wizardGadgets[key] = {id: newGadgetId, type: gadget.type};
141
-
142
- if (gadgets[key].onActions) {
143
- for (const handler of Object.keys(gadgets[key].onActions)) {
144
- quest.goblin.defer(
145
- quest.sub(`*::${newGadgetId}.${handler}`, function* (
146
- err,
147
- {msg, resp}
148
- ) {
149
- const cmdName = `${key}-${handler}`;
150
- yield resp.cmd(
151
- `${goblinName}.${cmdName}`,
152
- Object.assign({id}, msg.data)
153
- );
154
- })
155
- );
124
+ Goblin.registerQuest(
125
+ goblinName,
126
+ 'create',
127
+ function* (quest, desktopId, form, isDialog) {
128
+ const id = quest.goblin.id;
129
+ quest.goblin.setX('desktopId', desktopId);
130
+ quest.goblin.setX('isDialog', isDialog);
131
+ quest.goblin.setX('isDisposing', false);
132
+ const wizardGadgets = {};
133
+
134
+ if (gadgets) {
135
+ for (const key of Object.keys(gadgets)) {
136
+ const gadget = gadgets[key];
137
+ // const newGadgetId = `${gadget.type}@${quest.goblin.id}`;
138
+ const newGadgetId = `${key}@${quest.goblin.id}`; // Uses 'key' instead of 'gadget.type' to allow the same gadget to be used in a wizard more than once.
139
+ wizardGadgets[key] = {id: newGadgetId, type: gadget.type};
140
+
141
+ if (gadgets[key].onActions) {
142
+ for (const handler of Object.keys(gadgets[key].onActions)) {
143
+ quest.goblin.defer(
144
+ quest.sub(`*::${newGadgetId}.${handler}`, function* (
145
+ err,
146
+ {msg, resp}
147
+ ) {
148
+ const cmdName = `${key}-${handler}`;
149
+ yield resp.cmd(
150
+ `${goblinName}.${cmdName}`,
151
+ Object.assign({id}, msg.data)
152
+ );
153
+ })
154
+ );
155
+ }
156
156
  }
157
- }
158
157
 
159
- yield quest.create(`${gadget.type}-gadget`, {
160
- id: newGadgetId,
161
- desktopId,
162
- options: gadget.options || null,
163
- });
158
+ yield quest.create(`${gadget.type}-gadget`, {
159
+ id: newGadgetId,
160
+ desktopId,
161
+ options: gadget.options || null,
162
+ });
163
+ }
164
+ }
165
+ if (hinters) {
166
+ yield quest.me.createHinters();
164
167
  }
165
- }
166
- if (hinters) {
167
- yield quest.me.createHinters();
168
- }
169
-
170
- let running = 0;
171
168
 
172
- quest.goblin.defer(
173
- quest.sub.local(`*::${quest.goblin.id}.<wizard-tick>`, function* (
174
- err,
175
- {msg, resp}
176
- ) {
177
- const {calledFrom} = msg.data;
178
- const isInternal = calledFrom.split('.')[0] === quest.goblin.id;
179
- if (running > 0 && !isInternal) {
180
- return; /* Drop this tick because a step is already running */
181
- }
169
+ let running = 0;
170
+
171
+ quest.goblin.defer(
172
+ quest.sub.local(`*::${quest.goblin.id}.<wizard-tick>`, function* (
173
+ err,
174
+ {msg, resp}
175
+ ) {
176
+ const {calledFrom} = msg.data;
177
+ const isInternal = calledFrom.split('.')[0] === quest.goblin.id;
178
+ if (running > 0 && !isInternal) {
179
+ return; /* Drop this tick because a step is already running */
180
+ }
182
181
 
183
- try {
184
- ++running;
185
- const step = quest.goblin.getState().get('step');
186
- yield resp.cmd(`${goblinName}.${step}`, {id});
187
- } finally {
188
- --running;
189
- }
190
- })
191
- );
182
+ try {
183
+ ++running;
184
+ const step = quest.goblin.getState().get('step');
185
+ yield resp.cmd(`${goblinName}.${step}`, {id});
186
+ } finally {
187
+ --running;
188
+ }
189
+ })
190
+ );
192
191
 
193
- quest.do({id: quest.goblin.id, initialFormState, form, wizardGadgets});
194
- yield quest.me.initWizard();
195
- yield quest.me.idle();
196
- return quest.goblin.id;
197
- });
192
+ quest.do({id: quest.goblin.id, initialFormState, form, wizardGadgets});
193
+ yield quest.me.initWizard();
194
+ yield quest.me.idle();
195
+ return quest.goblin.id;
196
+ },
197
+ {skills: skills ?? []}
198
+ );
198
199
 
199
200
  Goblin.registerQuest(goblinName, 'create-hinters', function* (quest, next) {
200
201
  const desktopId = quest.goblin.getX('desktopId');
@@ -228,18 +229,18 @@ module.exports = (config) => {
228
229
 
229
230
  common.registerHinters(goblinName, hinters);
230
231
 
231
- Goblin.registerQuest(goblinName, 'busy', function (quest) {
232
+ Goblin.registerSafeQuest(goblinName, 'busy', function (quest) {
232
233
  quest.do();
233
234
  });
234
235
 
235
- Goblin.registerQuest(goblinName, 'idle', function (quest) {
236
+ Goblin.registerSafeQuest(goblinName, 'idle', function (quest) {
236
237
  quest.do();
237
238
  });
238
239
 
239
240
  if (gadgets) {
240
241
  for (const key of Object.keys(gadgets)) {
241
242
  //Gogo gadgeto stylo!
242
- Goblin.registerQuest(goblinName, `use-${key}`, function* (
243
+ Goblin.registerSafeQuest(goblinName, `use-${key}`, function* (
243
244
  quest,
244
245
  action,
245
246
  payload
@@ -255,7 +256,7 @@ module.exports = (config) => {
255
256
  for (const handler of Object.keys(gadgets[key].onActions)) {
256
257
  logicHandlers[`${key}-${handler}`] = gadgets[key].onActions[handler];
257
258
 
258
- Goblin.registerQuest(goblinName, `${key}-${handler}`, function* (
259
+ Goblin.registerSafeQuest(goblinName, `${key}-${handler}`, function* (
259
260
  quest
260
261
  ) {
261
262
  quest.do();
@@ -268,32 +269,32 @@ module.exports = (config) => {
268
269
 
269
270
  if (quests) {
270
271
  Object.keys(quests).forEach((q) => {
271
- Goblin.registerQuest(goblinName, q, quests[q]);
272
+ Goblin.registerSafeQuest(goblinName, q, quests[q]);
272
273
  });
273
274
  }
274
275
 
275
- Goblin.registerQuest(goblinName, 'init-wizard', function (quest) {
276
+ Goblin.registerSafeQuest(goblinName, 'init-wizard', function (quest) {
276
277
  quest.do();
277
278
  quest.evt('<wizard-tick>', {calledFrom: quest.calledFrom});
278
279
  });
279
280
 
280
- Goblin.registerQuest(goblinName, 'next', function (quest, result) {
281
+ Goblin.registerSafeQuest(goblinName, 'next', function (quest, result) {
281
282
  quest.do();
282
283
  quest.evt('<wizard-tick>', {calledFrom: quest.calledFrom});
283
284
  return result;
284
285
  });
285
286
 
286
- Goblin.registerQuest(goblinName, 'back', function (quest) {
287
+ Goblin.registerSafeQuest(goblinName, 'back', function (quest) {
287
288
  quest.do();
288
289
  quest.evt('<wizard-tick>', {calledFrom: quest.calledFrom});
289
290
  });
290
291
 
291
- Goblin.registerQuest(goblinName, 'goto', function (quest, step) {
292
+ Goblin.registerSafeQuest(goblinName, 'goto', function (quest, step) {
292
293
  quest.do();
293
294
  quest.evt('<wizard-tick>', {calledFrom: quest.calledFrom});
294
295
  });
295
296
 
296
- Goblin.registerQuest(goblinName, '_goto', function* (quest) {
297
+ Goblin.registerSafeQuest(goblinName, '_goto', function* (quest) {
297
298
  const state = quest.goblin.getState();
298
299
  const form = state.get('form').toJS();
299
300
  const nextStep = state.get('nextStep');
@@ -315,7 +316,7 @@ module.exports = (config) => {
315
316
  }
316
317
  });
317
318
 
318
- Goblin.registerQuest(goblinName, 'done', function* (quest) {
319
+ Goblin.registerSafeQuest(goblinName, 'done', function* (quest) {
319
320
  let result = quest.goblin.getState().get('result');
320
321
  if (Shredder.isImmutable(result)) {
321
322
  result = result.toJS();
@@ -328,12 +329,16 @@ module.exports = (config) => {
328
329
  yield quest.me.dispose();
329
330
  });
330
331
 
331
- Goblin.registerQuest(goblinName, 'cancel', function (quest) {
332
+ Goblin.registerSafeQuest(goblinName, 'cancel', function (quest) {
332
333
  quest.do();
333
334
  quest.evt('<wizard-tick>', {calledFrom: quest.calledFrom});
334
335
  });
335
336
 
336
- Goblin.registerQuest(goblinName, 'change', function* (quest, path, newValue) {
337
+ Goblin.registerSafeQuest(goblinName, 'change', function* (
338
+ quest,
339
+ path,
340
+ newValue
341
+ ) {
337
342
  if (hinters && hinters[path]) {
338
343
  return;
339
344
  }
@@ -341,12 +346,12 @@ module.exports = (config) => {
341
346
  yield quest.me.update();
342
347
  });
343
348
 
344
- Goblin.registerQuest(goblinName, 'apply', function* (quest) {
349
+ Goblin.registerSafeQuest(goblinName, 'apply', function* (quest) {
345
350
  quest.do();
346
351
  yield quest.me.update();
347
352
  });
348
353
 
349
- Goblin.registerQuest(goblinName, 'update', function* (quest) {
354
+ Goblin.registerSafeQuest(goblinName, 'update', function* (quest) {
350
355
  const state = quest.goblin.getState();
351
356
  const stepName = state.get('step');
352
357
  const step = steps[stepName];
@@ -362,7 +367,7 @@ module.exports = (config) => {
362
367
  }
363
368
  });
364
369
 
365
- Goblin.registerQuest(goblinName, 'update-buttons', function* (quest) {
370
+ Goblin.registerSafeQuest(goblinName, 'update-buttons', function* (quest) {
366
371
  const state = quest.goblin.getState();
367
372
  const stepName = state.get('step');
368
373
  const step = steps[stepName];
@@ -392,31 +397,35 @@ module.exports = (config) => {
392
397
  };
393
398
 
394
399
  if (step.quest) {
395
- Goblin.registerQuest(goblinName, stepName, step.quest);
400
+ Goblin.registerSafeQuest(goblinName, stepName, step.quest);
396
401
  }
397
402
 
398
403
  if (step.buttons) {
399
- Goblin.registerQuest(goblinName, `${stepName}-buttons`, step.buttons);
404
+ Goblin.registerSafeQuest(goblinName, `${stepName}-buttons`, step.buttons);
400
405
  }
401
406
 
402
407
  if (step.onChange) {
403
- Goblin.registerQuest(goblinName, `${stepName}-on-change`, step.onChange);
408
+ Goblin.registerSafeQuest(
409
+ goblinName,
410
+ `${stepName}-on-change`,
411
+ step.onChange
412
+ );
404
413
  }
405
414
 
406
415
  for (const action in step.actions) {
407
416
  const actionQuest = `${stepName}-${action}`;
408
417
  logicHandlers[actionQuest] = step.actions[action];
409
- Goblin.registerQuest(goblinName, actionQuest, function (quest) {
418
+ Goblin.registerSafeQuest(goblinName, actionQuest, function (quest) {
410
419
  quest.do();
411
420
  });
412
421
  }
413
422
  }
414
423
 
415
- Goblin.registerQuest(goblinName, 'get-entity', common.getEntityQuest);
416
- Goblin.registerQuest(goblinName, 'load-entity', common.loadEntityQuest);
417
- Goblin.registerQuest(goblinName, 'open-wizard', common.openWizard);
424
+ Goblin.registerSafeQuest(goblinName, 'get-entity', common.getEntityQuest);
425
+ Goblin.registerSafeQuest(goblinName, 'load-entity', common.loadEntityQuest);
426
+ Goblin.registerSafeQuest(goblinName, 'open-wizard', common.openWizard);
418
427
 
419
- Goblin.registerQuest(goblinName, 'showHinter', function* (
428
+ Goblin.registerSafeQuest(goblinName, 'showHinter', function* (
420
429
  quest,
421
430
  type,
422
431
  withDetail = true
@@ -430,14 +439,14 @@ module.exports = (config) => {
430
439
  }
431
440
  });
432
441
 
433
- Goblin.registerQuest(goblinName, 'hideHinter', function* (quest, type) {
442
+ Goblin.registerSafeQuest(goblinName, 'hideHinter', function* (quest, type) {
434
443
  const hinterAPI = quest
435
444
  .getAPI(`${type}-hinter@${quest.goblin.id}`)
436
445
  .noThrow();
437
446
  yield hinterAPI.hide();
438
447
  });
439
448
 
440
- Goblin.registerQuest(goblinName, 'setDetail', function* (
449
+ Goblin.registerSafeQuest(goblinName, 'setDetail', function* (
441
450
  quest,
442
451
  type,
443
452
  entityId
@@ -467,7 +476,7 @@ module.exports = (config) => {
467
476
  });
468
477
  }
469
478
 
470
- Goblin.registerQuest(goblinName, 'dispose', disposeQuest);
479
+ Goblin.registerSafeQuest(goblinName, 'dispose', disposeQuest);
471
480
 
472
481
  Goblin.registerQuest(goblinName, 'delete', function (quest) {
473
482
  quest.evt('done', {finished: true});
package/lib/service.js CHANGED
@@ -89,7 +89,10 @@ Goblin.registerQuest(goblinName, 'open', function* (
89
89
  if (serverTick === 0) {
90
90
  quest.dispatch('tick');
91
91
  const serverTickInterval = setInterval(
92
- () => busClient.command.send('desktop-manager.tick'),
92
+ () =>
93
+ busClient.command.send('desktop-manager.tick', null, null, null, {
94
+ forceNested: true,
95
+ }),
93
96
  60000
94
97
  );
95
98
  quest.goblin.defer(() => clearInterval(serverTickInterval));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goblin-desktop",
3
- "version": "2.0.0",
3
+ "version": "2.0.7",
4
4
  "description": "Goblin Desktop",
5
5
  "main": "./builders/builders.js",
6
6
  "scripts": {
@@ -11,7 +11,7 @@ import Button from 'goblin-gadgets/widgets/button/widget';
11
11
  import List from 'goblin-gadgets/widgets/list/widget';
12
12
  import DatagridEntity from './datagrid-entity.js';
13
13
  import DatagridHeaders from './datagrid-headers.js';
14
- import DatagridItem from './datagrid-item.js';
14
+ import DatagridItem from 'goblin-desktop/widgets/datagrid-item/widget';
15
15
 
16
16
  import importer from 'goblin_importer';
17
17
  const uiImporter = importer('ui');
@@ -81,6 +81,7 @@ class Datagrid extends Widget {
81
81
  renderListItem(props) {
82
82
  return (
83
83
  <DatagridItem
84
+ height={props.height ?? 40}
84
85
  renderItem={this.renderDatagridItem}
85
86
  onDrillDown={this.drillDown}
86
87
  {...props}
@@ -0,0 +1,15 @@
1
+ import {Unit} from 'goblin-theme';
2
+ const px = Unit.toPx;
3
+
4
+ /******************************************************************************/
5
+
6
+ export const propNames = ['height'];
7
+
8
+ export default function styles(theme, props) {
9
+ const row = {
10
+ minHeight: px(props.height),
11
+ maxHeight: px(props.height),
12
+ };
13
+
14
+ return {row};
15
+ }
@@ -4,10 +4,12 @@ import React from 'react';
4
4
  import Widget from 'goblin-laboratory/widgets/widget';
5
5
  import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
6
6
  import Container from 'goblin-gadgets/widgets/container/widget';
7
+ import * as styles from './styles';
7
8
 
8
9
  class DatagridItem extends Widget {
9
10
  constructor() {
10
11
  super(...arguments);
12
+ this.styles = styles;
11
13
 
12
14
  this.renewTTL = this.renewTTL.bind(this);
13
15
  this.renderItem = this.renderItem.bind(this);
@@ -54,18 +56,8 @@ class DatagridItem extends Widget {
54
56
  }
55
57
 
56
58
  render() {
57
- let {height} = this.props;
58
-
59
- if (height < 40) {
60
- height = 40;
61
- }
62
-
63
59
  return (
64
- <Container
65
- minHeight={`${height}px`}
66
- maxHeight={`${height}px`}
67
- kind="content"
68
- >
60
+ <Container className={this.styles.classNames.row} kind="content">
69
61
  {this.renderItem()}
70
62
  </Container>
71
63
  );
@@ -642,19 +642,28 @@ Goblin.registerQuest(goblinName, 'download-file', function (
642
642
  filePath,
643
643
  openFile
644
644
  ) {
645
- const labId = quest.goblin.getX('labId');
646
- const fs = require('fs');
647
- const stream = fs.createReadStream;
648
- const routingKey = require('xcraft-core-host').getRoutingKey();
649
- if (fs.existsSync(filePath)) {
650
- let file = stream(filePath);
651
- quest.evt(`wm@${labId}.download-file-requested`, {
652
- xcraftStream: file,
653
- routingKey,
654
- fileFilter: getFileFilter(filePath),
655
- defaultPath: path.basename(filePath),
656
- openFile,
657
- });
645
+ if (quest.user) {
646
+ const {sessionType, sessionId, windowId} = quest.user.getContext();
647
+ const clientSessionId = `${sessionType}@${sessionId}`;
648
+ const clientWindowId = windowId;
649
+ const fs = require('fs');
650
+ const stream = fs.createReadStream;
651
+ const routingKey = require('xcraft-core-host').getRoutingKey();
652
+ if (fs.existsSync(filePath)) {
653
+ let file = stream(filePath);
654
+ quest.evt(
655
+ `<${clientSessionId}-${clientWindowId}-download-file-requested>`,
656
+ {
657
+ xcraftStream: file,
658
+ routingKey,
659
+ fileFilter: getFileFilter(filePath),
660
+ defaultPath: path.basename(filePath),
661
+ openFile,
662
+ }
663
+ );
664
+ }
665
+ } else {
666
+ throw new Error('Cannot identifie user requesting download');
658
667
  }
659
668
  });
660
669
 
@@ -231,19 +231,19 @@ class EntityAlerts extends Widget {
231
231
  a.push(T('1 erreur'));
232
232
  }
233
233
  if (nError > 1) {
234
- a.push(T(`${nError} erreurs`, null, {nError}));
234
+ a.push(T('{nError} erreurs', null, {nError}));
235
235
  }
236
236
  if (nWarning === 1) {
237
237
  a.push(T('1 avertissement'));
238
238
  }
239
239
  if (nWarning > 1) {
240
- a.push(T(`${nWarning} avertissements`, null, {nWarning}));
240
+ a.push(T('{nWarning} avertissements', null, {nWarning}));
241
241
  }
242
242
  if (nInfo === 1) {
243
243
  a.push(T('1 information'));
244
244
  }
245
245
  if (nInfo > 1) {
246
- a.push(T(`${nInfo} informations`, null, {nInfo}));
246
+ a.push(T('{nInfo} informations', null, {nInfo}));
247
247
  }
248
248
  const message = StringBuilder.joinSentences(a);
249
249
 
@@ -74,7 +74,8 @@ export default function styles(theme, props) {
74
74
  position: 'relative',
75
75
  height: px(busyHeight),
76
76
  minHeight: '40px',
77
- top: '10px',
77
+ display: 'flex',
78
+ alignItems: 'center',
78
79
  };
79
80
 
80
81
  const filteredCellBarre = {
@@ -4,9 +4,9 @@ import Widget from 'goblin-laboratory/widgets/widget';
4
4
  import TableCell from 'goblin-gadgets/widgets/table-cell/widget';
5
5
  import Gauge from 'goblin-gadgets/widgets/gauge/widget';
6
6
  import Label from 'goblin-gadgets/widgets/label/widget';
7
+ import Spinner from 'goblin-gadgets/widgets/spinner/widget';
7
8
  import ColoredContainer from 'goblin-gadgets/widgets/colored-container/widget';
8
9
  import EntityRowButton from 'goblin-desktop/widgets/entity-row-button/widget';
9
- import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
10
10
  import T from 't';
11
11
  import ListHelpers from 'goblin-workshop/lib/list-helpers.js';
12
12
  import RetroGear from 'goblin-gadgets/widgets/retro-gear/widget';
@@ -59,7 +59,7 @@ class _Driller extends Widget {
59
59
  </div>
60
60
  );
61
61
  } else {
62
- return <FontAwesomeIcon icon={[`fas`, 'spinner']} size={'1x'} pulse />;
62
+ <Spinner size="24px" />;
63
63
  }
64
64
  }
65
65
 
@@ -449,7 +449,7 @@ class EntityRow extends Widget {
449
449
  } else {
450
450
  return (
451
451
  <div className={this.styles.classNames.spinner}>
452
- <FontAwesomeIcon icon={[`fas`, 'spinner']} size={'1x'} pulse />
452
+ <Spinner size="24px" />
453
453
  </div>
454
454
  );
455
455
  }
@@ -42,8 +42,8 @@ export default function styles(theme) {
42
42
 
43
43
  const closeButton = {
44
44
  position: 'absolute',
45
- top: '0px',
46
- right: '0px',
45
+ top: '10px',
46
+ right: '10px',
47
47
  };
48
48
 
49
49
  return {
@@ -80,50 +80,50 @@ class FacetFilterListDialog extends Widget {
80
80
  /******************************************************************************/
81
81
 
82
82
  renderClose() {
83
- return null;
84
- //- return (
85
- //- <div className={this.styles.classNames.closeButton}>
86
- //- <Button
87
- //- border="none"
88
- //- glyph="solid/times"
89
- //- glyphSize="120%"
90
- //- height="32px"
91
- //- width="32px"
92
- //- onClick={this.onClose}
93
- //- />
94
- //- </div>
95
- //- );
96
- }
97
-
98
- renderHeader(keys) {
99
- if (this.props.numberOfCheckboxes <= 5) {
100
- return null;
101
- }
102
-
103
83
  return (
104
- <div className={this.styles.classNames.header}>
105
- <Label text={T('Filtre')} />
106
- <TextFieldNC
107
- width="300px"
108
- shape={this.filter ? 'left-rounded' : 'rounded'}
109
- value={this.filter}
110
- changeMode="throttled"
111
- throttleDelay={200}
112
- onChange={this.filterChange}
113
- />
84
+ <div className={this.styles.classNames.closeButton}>
114
85
  <Button
115
- kind="combo"
116
- shape="right-rounded"
117
- leftSpacing="overlap"
118
- glyph="solid/eraser"
119
- tooltip={T('Tout montrer')}
120
- show={!!this.filter}
121
- onClick={() => this.filterChange(null)}
86
+ border="none"
87
+ glyph="solid/times"
88
+ glyphSize="120%"
89
+ tooltip={T('Fermer')}
90
+ height="32px"
91
+ width="32px"
92
+ onClick={this.onClose}
122
93
  />
123
94
  </div>
124
95
  );
125
96
  }
126
97
 
98
+ renderHeader(keys) {
99
+ if (this.props.numberOfCheckboxes <= 5) {
100
+ return <div className={this.styles.classNames.header}></div>;
101
+ } else {
102
+ return (
103
+ <div className={this.styles.classNames.header}>
104
+ <Label text={T('Filtre')} />
105
+ <TextFieldNC
106
+ width="300px"
107
+ shape={this.filter ? 'left-rounded' : 'rounded'}
108
+ value={this.filter}
109
+ changeMode="throttled"
110
+ throttleDelay={200}
111
+ onChange={this.filterChange}
112
+ />
113
+ <Button
114
+ kind="combo"
115
+ shape="right-rounded"
116
+ leftSpacing="overlap"
117
+ glyph="solid/eraser"
118
+ tooltip={T('Tout montrer')}
119
+ show={!!this.filter}
120
+ onClick={() => this.filterChange(null)}
121
+ />
122
+ </div>
123
+ );
124
+ }
125
+ }
126
+
127
127
  renderFooter(keys) {
128
128
  return (
129
129
  <FacetFilterListDialogFooter
@@ -59,8 +59,8 @@ export default function styles(theme) {
59
59
 
60
60
  const closeButton = {
61
61
  position: 'absolute',
62
- top: '0px',
63
- right: '0px',
62
+ top: '10px',
63
+ right: '10px',
64
64
  };
65
65
 
66
66
  return {
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import Widget from 'goblin-laboratory/widgets/widget';
3
3
  import DialogModal from 'goblin-gadgets/widgets/dialog-modal/widget';
4
4
  import Label from 'goblin-gadgets/widgets/label/widget';
5
+ import Button from 'goblin-gadgets/widgets/button/widget';
5
6
  import TextFieldTypedNC from 'goblin-gadgets/widgets/text-field-typed-nc/widget';
6
7
  import Slider from 'goblin-gadgets/widgets/slider/widget';
7
8
  import CheckList from 'goblin-gadgets/widgets/check-list/widget';
@@ -124,19 +125,19 @@ class FacetFilterRangeDialog extends Widget {
124
125
  /******************************************************************************/
125
126
 
126
127
  renderClose() {
127
- return null;
128
- //- return (
129
- //- <div className={this.styles.classNames.closeButton}>
130
- //- <Button
131
- //- border="none"
132
- //- glyph="solid/times"
133
- //- glyphSize="120%"
134
- //- height="32px"
135
- //- width="32px"
136
- //- onClick={this.onClose}
137
- //- />
138
- //- </div>
139
- //- );
128
+ return (
129
+ <div className={this.styles.classNames.closeButton}>
130
+ <Button
131
+ border="none"
132
+ glyph="solid/times"
133
+ glyphSize="120%"
134
+ tooltip={T('Fermer')}
135
+ height="32px"
136
+ width="32px"
137
+ onClick={this.onClose}
138
+ />
139
+ </div>
140
+ );
140
141
  }
141
142
 
142
143
  renderRadios() {
@@ -9,6 +9,7 @@ import throttle from 'lodash/throttle';
9
9
  import Container from 'goblin-gadgets/widgets/container/widget';
10
10
  import Label from 'goblin-gadgets/widgets/label/widget';
11
11
  import Button from 'goblin-gadgets/widgets/button/widget';
12
+ import CommandButton from 'goblin-gadgets/widgets/command-button/widget';
12
13
  import StatusFilters from 'goblin-desktop/widgets/status-filters/widget';
13
14
  import C from 'goblin-laboratory/widgets/connect-helpers/c';
14
15
  import TextField from 'goblin-gadgets/widgets/text-field/widget';
@@ -46,7 +47,7 @@ class HinterNewButton extends Widget {
46
47
  }
47
48
 
48
49
  render() {
49
- const {id, onNew, title} = this.props;
50
+ const {id, onNew, title, type} = this.props;
50
51
 
51
52
  if (!id) {
52
53
  return null;
@@ -54,7 +55,8 @@ class HinterNewButton extends Widget {
54
55
  return (
55
56
  <>
56
57
  {onNew ? (
57
- <Button
58
+ <CommandButton
59
+ command={`${type}-workitem.edit`}
58
60
  kind="action"
59
61
  place="1/1"
60
62
  glyph="solid/plus"
@@ -25,6 +25,7 @@ class Tab extends Widget {
25
25
  this.cmd('desktop.removeWorkitem', {
26
26
  id: this.props.desktopId,
27
27
  workitemId,
28
+ close: true,
28
29
  });
29
30
  SFX.blop.play();
30
31
  }
@@ -5,6 +5,7 @@ import Widget from 'goblin-laboratory/widgets/widget';
5
5
 
6
6
  import Container from 'goblin-gadgets/widgets/container/widget';
7
7
  import Button from 'goblin-gadgets/widgets/button/widget';
8
+ import CommandButton from 'goblin-gadgets/widgets/command-button/widget';
8
9
  import Separator from 'goblin-gadgets/widgets/separator/widget';
9
10
  import SFX from '../audio/sfx.js';
10
11
 
@@ -50,9 +51,11 @@ class Taskbar extends Widget {
50
51
  renderButton(context, task, index) {
51
52
  if (task.workitem) {
52
53
  const runWorkitem = () => this.runWorkitem(task.workitem, task.context);
54
+ const command = `${task.workitem.name}.create`;
53
55
  return (
54
- <Button
56
+ <CommandButton
55
57
  key={index}
58
+ command={command}
56
59
  kind="task-bar"
57
60
  text={task.text}
58
61
  glyph={task.glyph}
@@ -141,12 +144,7 @@ class Taskbar extends Widget {
141
144
  }
142
145
  }
143
146
 
144
- let canDo = true;
145
- if (task.workitem) {
146
- canDo = this.canDo(`${task.workitem.name}.create`);
147
- }
148
-
149
- if (isValidScope && canDo) {
147
+ if (isValidScope) {
150
148
  if (task.separator) {
151
149
  return this.renderSeparator(i);
152
150
  } else {
@@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
7
7
  import Container from 'goblin-gadgets/widgets/container/widget';
8
8
  import Label from 'goblin-gadgets/widgets/label/widget';
9
9
  import Button from 'goblin-gadgets/widgets/button/widget';
10
+ import CommandButton from 'goblin-gadgets/widgets/command-button/widget';
10
11
  import ScrollableContainer from 'goblin-gadgets/widgets/scrollable-container/widget';
11
12
  import DialogModal from 'goblin-gadgets/widgets/dialog-modal/widget';
12
13
  import CheckList from 'goblin-gadgets/widgets/check-list/widget';
@@ -27,7 +28,7 @@ class Workitem extends Form {
27
28
 
28
29
  this.doAction = this.doAction.bind(this);
29
30
  this.onSubmit = this.onSubmit.bind(this);
30
- this.onCancel = this.onCancel.bind(this);
31
+ this.onRollback = this.onRollback.bind(this);
31
32
  this.onClose = this.onClose.bind(this);
32
33
  this.onEdit = this.onEdit.bind(this);
33
34
  this.onTrash = this.onTrash.bind(this);
@@ -109,6 +110,29 @@ class Workitem extends Form {
109
110
  return this.context.contextId;
110
111
  }
111
112
 
113
+ getCommand(button) {
114
+ const getQuest = (id) => {
115
+ switch (id) {
116
+ case 'rollback':
117
+ case 'validate':
118
+ return `close`;
119
+ case 'delete':
120
+ return `trash-entity`;
121
+ case 'submit':
122
+ case 'publish':
123
+ case 'trash':
124
+ case 'archive':
125
+ return `${id}-entity`;
126
+ default:
127
+ return id;
128
+ }
129
+ };
130
+
131
+ const service = button.questService ?? this.props.id.split('@', 1)[0];
132
+ let quest = button.quest ?? getQuest(button.id);
133
+ return `${service}.${quest}`;
134
+ }
135
+
112
136
  onSubmit() {
113
137
  this.doAs(this.service, 'close', {
114
138
  kind: 'validate',
@@ -116,8 +140,11 @@ class Workitem extends Form {
116
140
  });
117
141
  }
118
142
 
119
- onCancel() {
120
- this.doAs(this.service, 'restore-entity');
143
+ onRollback() {
144
+ this.doAs(this.service, 'close', {
145
+ kind: 'rollback',
146
+ desktopId: this.desktopId,
147
+ });
121
148
  //TODO-VNEXT: REPAIR ME
122
149
  //this.hideHinter();
123
150
  }
@@ -230,8 +257,8 @@ class Workitem extends Form {
230
257
  case 'edit':
231
258
  this.onEdit();
232
259
  break;
233
- case 'reset':
234
- this.onCancel();
260
+ case 'rollback':
261
+ this.onRollback();
235
262
  break;
236
263
  case 'delete':
237
264
  this.onDelete();
@@ -256,6 +283,7 @@ class Workitem extends Form {
256
283
  }
257
284
 
258
285
  renderActionListButton(button, hasStature, index) {
286
+ const command = this.getCommand(button);
259
287
  return (
260
288
  <div
261
289
  key={index}
@@ -265,7 +293,8 @@ class Workitem extends Form {
265
293
  : this.styles.classNames.actionList
266
294
  }
267
295
  >
268
- <Button
296
+ <CommandButton
297
+ command={command}
269
298
  kind="secondary-action"
270
299
  grow="1"
271
300
  place="1/1"
@@ -370,9 +399,11 @@ class Workitem extends Form {
370
399
 
371
400
  renderActionButton(button, layout, index, count) {
372
401
  const secondary = layout === 'secondary';
373
-
402
+ const command = this.getCommand(button);
403
+ console.log('renderActionButton', command);
374
404
  return (
375
- <Button
405
+ <CommandButton
406
+ command={command}
376
407
  key={index}
377
408
  kind={secondary ? 'secondary-action' : 'action'}
378
409
  width={secondary ? null : '0px'}