@performant-software/semantic-components 0.5.5 → 0.5.6

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.
@@ -13,6 +13,7 @@ import {
13
13
  import _ from 'underscore';
14
14
  import i18n from '../i18n/i18n';
15
15
  import FileUpload from './FileUpload';
16
+ import ModalContext from '../context/ModalContext';
16
17
  import Toaster from './Toaster';
17
18
 
18
19
  type Props = {
@@ -195,44 +196,48 @@ class FileUploadModal extends Component<Props, State> {
195
196
  />
196
197
  )}
197
198
  { this.state.modal && (
198
- <Modal
199
- centered={false}
200
- className='file-upload-modal'
201
- open
202
- >
203
- <Dimmer
204
- active={this.state.saving}
205
- inverted
206
- >
207
- <Loader
208
- content={i18n.t('FileUploadModal.loader')}
209
- />
210
- </Dimmer>
211
- { this.renderErrors() }
212
- <Modal.Header
213
- content={this.props.title || i18n.t('FileUploadModal.title')}
214
- />
215
- <Modal.Content>
216
- <FileUpload
217
- onFilesAdded={this.onAddFiles.bind(this)}
218
- />
219
- { this.renderItems() }
220
- </Modal.Content>
221
- <Modal.Actions>
222
- <Button
223
- content={i18n.t('Common.buttons.save')}
224
- disabled={!(this.state.items && this.state.items.length)}
225
- primary
226
- onClick={this.onSave.bind(this)}
227
- />
228
- <Button
229
- content={i18n.t('Common.buttons.cancel')}
230
- inverted
231
- primary
232
- onClick={this.onClose.bind(this)}
233
- />
234
- </Modal.Actions>
235
- </Modal>
199
+ <ModalContext.Consumer>
200
+ { (mountNode) => (
201
+ <Modal
202
+ centered={false}
203
+ className='file-upload-modal'
204
+ mountNode={mountNode}
205
+ open
206
+ >
207
+ <Dimmer
208
+ active={this.state.saving}
209
+ inverted
210
+ >
211
+ <Loader
212
+ content={i18n.t('FileUploadModal.loader')}
213
+ />
214
+ </Dimmer>
215
+ { this.renderErrors() }
216
+ <Modal.Header
217
+ content={this.props.title || i18n.t('FileUploadModal.title')}
218
+ />
219
+ <Modal.Content>
220
+ <FileUpload
221
+ onFilesAdded={this.onAddFiles.bind(this)}
222
+ />
223
+ { this.renderItems() }
224
+ </Modal.Content>
225
+ <Modal.Actions>
226
+ <Button
227
+ content={i18n.t('Common.buttons.save')}
228
+ disabled={!(this.state.items && this.state.items.length)}
229
+ primary
230
+ onClick={this.onSave.bind(this)}
231
+ />
232
+ <Button
233
+ basic
234
+ content={i18n.t('Common.buttons.cancel')}
235
+ onClick={this.onClose.bind(this)}
236
+ />
237
+ </Modal.Actions>
238
+ </Modal>
239
+ )}
240
+ </ModalContext.Consumer>
236
241
  )}
237
242
  </>
238
243
  );
@@ -14,6 +14,7 @@ import {
14
14
  import _ from 'underscore';
15
15
  import i18n from '../i18n/i18n';
16
16
  import DateField from './DateInput';
17
+ import ModalContext from '../context/ModalContext';
17
18
  import './FuzzyDate.css';
18
19
 
19
20
  type DateInput = {
@@ -334,110 +335,119 @@ class FuzzyDate extends Component<Props, State> {
334
335
  onClick={this.onEdit.bind(this)}
335
336
  onChange={this.onClear.bind(this)}
336
337
  />
337
- <Modal
338
- as={Form}
339
- className='fuzzy-date-modal'
340
- open={this.state.modal}
341
- onClose={this.onClose.bind(this)}
342
- >
343
- <Modal.Header
344
- content={this.props.title || i18n.t('FuzzyDate.title')}
345
- />
346
- <Modal.Content>
347
- <Form.Input
348
- className='accuracy-container'
349
- label={i18n.t('FuzzyDate.labels.accuracy')}
338
+ <ModalContext.Consumer>
339
+ { (mountNode) => (
340
+ <Modal
341
+ as={Form}
342
+ className='fuzzy-date-modal'
343
+ mountNode={mountNode}
344
+ open={this.state.modal}
345
+ onClose={this.onClose.bind(this)}
350
346
  >
351
- <Checkbox
352
- checked={this.state.accuracy === ACCURACY_YEAR}
353
- label={i18n.t('FuzzyDate.accuracy.year')}
354
- name='accuracy'
355
- onChange={this.onAccuracyChange.bind(this)}
356
- radio
357
- value={ACCURACY_YEAR}
347
+ <Modal.Header
348
+ content={this.props.title || i18n.t('FuzzyDate.title')}
358
349
  />
359
- <Checkbox
360
- checked={this.state.accuracy === ACCURACY_MONTH}
361
- label={i18n.t('FuzzyDate.accuracy.month')}
362
- name='accuracy'
363
- onChange={this.onAccuracyChange.bind(this)}
364
- radio
365
- value={ACCURACY_MONTH}
366
- />
367
- <Checkbox
368
- checked={this.state.accuracy === ACCURACY_DATE}
369
- label={i18n.t('FuzzyDate.accuracy.date')}
370
- name='accuracy'
371
- onChange={this.onAccuracyChange.bind(this)}
372
- radio
373
- value={ACCURACY_DATE}
374
- />
375
- </Form.Input>
376
- <Form.Group>
377
- { this.renderYear('startDate') }
378
- { this.renderMonth('startDate') }
379
- { this.renderDate('startDate') }
380
- { !this.state.range && (
381
- <div
382
- className='button-container'
350
+ <Modal.Content>
351
+ <Form.Input
352
+ className='accuracy-container'
353
+ label={i18n.t('FuzzyDate.labels.accuracy')}
383
354
  >
384
- <Button
385
- basic
386
- content={i18n.t('FuzzyDate.buttons.addRange')}
387
- icon='plus'
388
- onClick={this.onRangeChange.bind(this)}
355
+ <Checkbox
356
+ checked={this.state.accuracy === ACCURACY_YEAR}
357
+ id='accuracy-year'
358
+ label={i18n.t('FuzzyDate.accuracy.year')}
359
+ name='accuracy'
360
+ onChange={this.onAccuracyChange.bind(this)}
361
+ radio
362
+ value={ACCURACY_YEAR}
389
363
  />
390
- </div>
391
- )}
392
- </Form.Group>
393
- { this.state.range && (
394
- <Form.Group>
395
- { this.renderYear('endDate') }
396
- { this.renderMonth('endDate') }
397
- { this.renderDate('endDate') }
398
- <div
399
- className='button-container'
400
- >
401
- <Button
402
- basic
403
- content={i18n.t('FuzzyDate.buttons.removeRange')}
404
- icon='times'
405
- onClick={this.onRangeChange.bind(this)}
364
+ <Checkbox
365
+ checked={this.state.accuracy === ACCURACY_MONTH}
366
+ id='accuracy-month'
367
+ label={i18n.t('FuzzyDate.accuracy.month')}
368
+ name='accuracy'
369
+ onChange={this.onAccuracyChange.bind(this)}
370
+ radio
371
+ value={ACCURACY_MONTH}
406
372
  />
407
- </div>
408
- </Form.Group>
409
- )}
410
- { this.props.description && (
411
- <Form.Input
412
- label={i18n.t('FuzzyDate.labels.description')}
413
- >
414
- <TextArea
415
- onChange={this.onDescriptionChange.bind(this)}
416
- value={this.state.description}
417
- />
418
- </Form.Input>
419
- )}
420
- </Modal.Content>
421
- <Modal.Actions>
422
- <Button
423
- onClick={this.onSave.bind(this)}
424
- primary
425
- size='medium'
426
- type='submit'
427
- >
428
- { i18n.t('Common.buttons.save') }
429
- </Button>
430
- <Button
431
- inverted
432
- onClick={this.onClose.bind(this)}
433
- primary
434
- size='medium'
435
- type='button'
436
- >
437
- { i18n.t('Common.buttons.cancel') }
438
- </Button>
439
- </Modal.Actions>
440
- </Modal>
373
+ <Checkbox
374
+ checked={this.state.accuracy === ACCURACY_DATE}
375
+ id='accuracy-date'
376
+ label={i18n.t('FuzzyDate.accuracy.date')}
377
+ name='accuracy'
378
+ onChange={this.onAccuracyChange.bind(this)}
379
+ radio
380
+ value={ACCURACY_DATE}
381
+ />
382
+ </Form.Input>
383
+ <Form.Group>
384
+ { this.renderYear('startDate') }
385
+ { this.renderMonth('startDate') }
386
+ { this.renderDate('startDate') }
387
+ { !this.state.range && (
388
+ <div
389
+ className='button-container'
390
+ >
391
+ <Button
392
+ basic
393
+ content={i18n.t('FuzzyDate.buttons.addRange')}
394
+ icon='plus'
395
+ onClick={this.onRangeChange.bind(this)}
396
+ />
397
+ </div>
398
+ )}
399
+ </Form.Group>
400
+ { this.state.range && (
401
+ <Form.Group>
402
+ { this.renderYear('endDate') }
403
+ { this.renderMonth('endDate') }
404
+ { this.renderDate('endDate') }
405
+ <div
406
+ className='button-container'
407
+ >
408
+ <Button
409
+ basic
410
+ content={i18n.t('FuzzyDate.buttons.removeRange')}
411
+ icon='times'
412
+ onClick={this.onRangeChange.bind(this)}
413
+ />
414
+ </div>
415
+ </Form.Group>
416
+ )}
417
+ { this.props.description && (
418
+ <Form.Input
419
+ id='description'
420
+ label={i18n.t('FuzzyDate.labels.description')}
421
+ >
422
+ <TextArea
423
+ id='description'
424
+ onChange={this.onDescriptionChange.bind(this)}
425
+ value={this.state.description}
426
+ />
427
+ </Form.Input>
428
+ )}
429
+ </Modal.Content>
430
+ <Modal.Actions>
431
+ <Button
432
+ onClick={this.onSave.bind(this)}
433
+ primary
434
+ size='medium'
435
+ type='submit'
436
+ >
437
+ { i18n.t('Common.buttons.save') }
438
+ </Button>
439
+ <Button
440
+ basic
441
+ onClick={this.onClose.bind(this)}
442
+ size='medium'
443
+ type='button'
444
+ >
445
+ { i18n.t('Common.buttons.cancel') }
446
+ </Button>
447
+ </Modal.Actions>
448
+ </Modal>
449
+ )}
450
+ </ModalContext.Consumer>
441
451
  </>
442
452
  );
443
453
  }
@@ -459,6 +469,7 @@ class FuzzyDate extends Component<Props, State> {
459
469
 
460
470
  return (
461
471
  <Form.Input
472
+ id='date-dropdown'
462
473
  label={i18n.t('FuzzyDate.labels.date')}
463
474
  >
464
475
  <Dropdown
@@ -486,9 +497,11 @@ class FuzzyDate extends Component<Props, State> {
486
497
 
487
498
  return (
488
499
  <Form.Input
500
+ id='month-dropdown'
489
501
  label={i18n.t('FuzzyDate.labels.month')}
490
502
  >
491
503
  <Dropdown
504
+ id='month-dropdown'
492
505
  onChange={this.onMonthChange.bind(this, property)}
493
506
  options={_.map(this.state.calendar.listMonths(), (m, i) => ({ key: i, value: i, text: m }))}
494
507
  selection
@@ -508,9 +521,11 @@ class FuzzyDate extends Component<Props, State> {
508
521
  renderYear(property: string) {
509
522
  return (
510
523
  <Form.Input
524
+ id='year'
511
525
  label={i18n.t('FuzzyDate.labels.year')}
512
526
  >
513
527
  <Input
528
+ id='year'
514
529
  onChange={this.onYearChange.bind(this, property)}
515
530
  type='number'
516
531
  value={this.state[property].year || ''}
@@ -23,6 +23,7 @@ import i18n from '../i18n/i18n';
23
23
  import AssociatedDropdown from './AssociatedDropdown';
24
24
  import DropdownButton from './DropdownButton';
25
25
  import FuzzyDate from './FuzzyDate';
26
+ import ModalContext from '../context/ModalContext';
26
27
 
27
28
  type Option = {
28
29
  key: string | number,
@@ -286,118 +287,123 @@ const ListFilters = (props: Props) => {
286
287
  }, []);
287
288
 
288
289
  return (
289
- <Modal
290
- as={Form}
291
- centered={false}
292
- className='list-filters-modal'
293
- noValidate
294
- open
295
- size='small'
296
- >
297
- <Modal.Header>
298
- <Grid
299
- columns={2}
290
+ <ModalContext.Consumer>
291
+ { (mountNode) => (
292
+ <Modal
293
+ as={Form}
294
+ centered={false}
295
+ className='list-filters-modal'
296
+ mountNode={mountNode}
297
+ noValidate
298
+ open
299
+ size='small'
300
300
  >
301
- <Grid.Column
302
- verticalAlign='middle'
303
- >
304
- <Header
305
- content={i18n.t('ListFilters.title')}
306
- />
307
- </Grid.Column>
308
- <Grid.Column
309
- textAlign='right'
310
- >
311
- <DropdownButton
312
- color='green'
313
- icon='plus'
314
- options={_.map(filters, (filter) => ({
315
- key: filter.key,
316
- value: filter.key,
317
- text: filter.label
318
- }))}
319
- onChange={(e, { value }) => {
320
- const filter = _.findWhere(props.filters, { key: value });
321
- props.onSaveChildAssociation('filters', {
322
- ...filter,
323
- uid: uuid(),
324
- operator: Operators.equal
325
- });
326
- }}
327
- scrolling
328
- text={i18n.t('ListFilters.buttons.add')}
329
- value=''
330
- />
331
- <Button
332
- color='red'
333
- content={i18n.t('ListFilters.buttons.reset')}
334
- icon='repeat'
335
- onClick={() => props.onReset()}
336
- style={{
337
- marginLeft: '1em'
338
- }}
339
- />
340
- </Grid.Column>
341
- </Grid>
342
- </Modal.Header>
343
- <Modal.Content>
344
- { !_.isEmpty(props.item.filters) && (
345
- <Grid>
346
- { _.map(props.item.filters, (filter) => (
347
- <Grid.Row
348
- columns={4}
349
- key={filter.key}
301
+ <Modal.Header>
302
+ <Grid
303
+ columns={2}
304
+ >
305
+ <Grid.Column
350
306
  verticalAlign='middle'
351
307
  >
352
- <Grid.Column>
353
- <Header
354
- content={filter.label}
355
- />
356
- </Grid.Column>
357
- <Grid.Column
358
- width={5}
359
- >
360
- <Dropdown
361
- options={getOperatorsByType(filter.type)}
362
- onChange={(e, { value }) => props.onSaveChildAssociation('filters', {
363
- ..._.omit(filter, 'value'),
364
- operator: value,
365
- })}
366
- selection
367
- value={filter.operator}
368
- />
369
- </Grid.Column>
370
- <Grid.Column
371
- width={5}
372
- >
373
- { renderInput(filter) }
374
- </Grid.Column>
375
- <Grid.Column
376
- width={1}
377
- >
378
- <Button
379
- basic
380
- icon='times'
381
- onClick={() => {
382
- /*
383
- * If we're removing the last filter, call the onReset prop to ensure the UI doesn't display
384
- * as active.
385
- */
386
- if (props.item.filters && props.item.filters.length === 1) {
387
- props.onReset();
388
- } else {
389
- props.onDeleteChildAssociation('filters', filter);
390
- }
391
- }}
392
- />
393
- </Grid.Column>
394
- </Grid.Row>
395
- ))}
396
- </Grid>
397
- )}
398
- </Modal.Content>
399
- { props.children }
400
- </Modal>
308
+ <Header
309
+ content={i18n.t('ListFilters.title')}
310
+ />
311
+ </Grid.Column>
312
+ <Grid.Column
313
+ textAlign='right'
314
+ >
315
+ <DropdownButton
316
+ color='green'
317
+ icon='plus'
318
+ options={_.map(filters, (filter) => ({
319
+ key: filter.key,
320
+ value: filter.key,
321
+ text: filter.label
322
+ }))}
323
+ onChange={(e, { value }) => {
324
+ const filter = _.findWhere(props.filters, { key: value });
325
+ props.onSaveChildAssociation('filters', {
326
+ ...filter,
327
+ uid: uuid(),
328
+ operator: Operators.equal
329
+ });
330
+ }}
331
+ scrolling
332
+ text={i18n.t('ListFilters.buttons.add')}
333
+ value=''
334
+ />
335
+ <Button
336
+ color='red'
337
+ content={i18n.t('ListFilters.buttons.reset')}
338
+ icon='repeat'
339
+ onClick={() => props.onReset()}
340
+ style={{
341
+ marginLeft: '1em'
342
+ }}
343
+ />
344
+ </Grid.Column>
345
+ </Grid>
346
+ </Modal.Header>
347
+ <Modal.Content>
348
+ { !_.isEmpty(props.item.filters) && (
349
+ <Grid>
350
+ { _.map(props.item.filters, (filter) => (
351
+ <Grid.Row
352
+ columns={4}
353
+ key={filter.key}
354
+ verticalAlign='middle'
355
+ >
356
+ <Grid.Column>
357
+ <Header
358
+ content={filter.label}
359
+ />
360
+ </Grid.Column>
361
+ <Grid.Column
362
+ width={5}
363
+ >
364
+ <Dropdown
365
+ options={getOperatorsByType(filter.type)}
366
+ onChange={(e, { value }) => props.onSaveChildAssociation('filters', {
367
+ ..._.omit(filter, 'value'),
368
+ operator: value,
369
+ })}
370
+ selection
371
+ value={filter.operator}
372
+ />
373
+ </Grid.Column>
374
+ <Grid.Column
375
+ width={5}
376
+ >
377
+ { renderInput(filter) }
378
+ </Grid.Column>
379
+ <Grid.Column
380
+ width={1}
381
+ >
382
+ <Button
383
+ basic
384
+ icon='times'
385
+ onClick={() => {
386
+ /*
387
+ * If we're removing the last filter, call the onReset prop to ensure the UI doesn't display
388
+ * as active.
389
+ */
390
+ if (props.item.filters && props.item.filters.length === 1) {
391
+ props.onReset();
392
+ } else {
393
+ props.onDeleteChildAssociation('filters', filter);
394
+ }
395
+ }}
396
+ />
397
+ </Grid.Column>
398
+ </Grid.Row>
399
+ ))}
400
+ </Grid>
401
+ )}
402
+ </Modal.Content>
403
+ { props.children }
404
+ </Modal>
405
+ )}
406
+ </ModalContext.Consumer>
401
407
  );
402
408
  };
403
409
 
@@ -10,6 +10,8 @@ import type { Column } from './DataTable';
10
10
 
11
11
  type Props = {
12
12
  columns: Array<Column>,
13
+ defaultSort?: string,
14
+ defaultSortDirection?: string,
13
15
  page: number,
14
16
  onSort: (sortColumn: string, sortDirection: string, page?: number) => void,
15
17
  onInit: (page?: number) => void,
@@ -49,12 +51,13 @@ const ListTable = (props: Props) => {
49
51
  * sortable column.
50
52
  */
51
53
  useEffect(() => {
52
- const { page, sortColumn, sortDirection = SORT_ASCENDING } = props;
54
+ const { page, defaultSort, defaultSortDirection = SORT_ASCENDING } = props;
53
55
 
54
- if (props.sortColumn) {
55
- props.onSort(sortColumn, sortDirection, page);
56
+ if (defaultSort) {
57
+ props.onSort(defaultSort, defaultSortDirection, page);
56
58
  } else {
57
59
  const sortableColumn = _.findWhere(props.columns, { sortable: true });
60
+
58
61
  if (sortableColumn) {
59
62
  onColumnClick(sortableColumn);
60
63
  } else {
@@ -62,7 +65,7 @@ const ListTable = (props: Props) => {
62
65
  props.onInit();
63
66
  }
64
67
  }
65
- }, []);
68
+ }, [props.columns]);
66
69
 
67
70
  return (
68
71
  <DataTable