@imposium-hub/components 1.58.5 → 1.58.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.
@@ -62,6 +62,15 @@ class AssetDetails extends React.Component<IAssetDetailsProps, IAssetDetailsStat
62
62
  const nameSubmit = !newAsset ? (e) => this.props.onNameChange(e) : undefined;
63
63
  const nameChange = newAsset ? (e) => this.props.onNameChange(e) : undefined;
64
64
 
65
+ const assetIdField = (
66
+ <TextField
67
+ readOnly={true}
68
+ width='25%'
69
+ showCopy={true}
70
+ value={asset.id}
71
+ />
72
+ );
73
+
65
74
  const nameField = (
66
75
  <TextField
67
76
  label={copy.name}
@@ -106,6 +115,7 @@ class AssetDetails extends React.Component<IAssetDetailsProps, IAssetDetailsStat
106
115
  return (
107
116
  <div className='asset-details'>
108
117
  <h2>{title}</h2>
118
+ {assetIdField}
109
119
  <div className='header-buttons'>{this.props.headerButtons}</div>
110
120
  <HRule />
111
121
  {nameField}
@@ -8,6 +8,7 @@ import { bindActionCreators } from 'redux';
8
8
  import { IImposiumAPI } from '../../services/API';
9
9
  import Button from '../button/Button';
10
10
  import { ICON_TIMES } from '../../constants/icons';
11
+ import { getAssetTagList } from '../../redux/actions/asset-tags';
11
12
 
12
13
  interface IAssetsTableTagsPivotProps {
13
14
  row: any; // React table row wrapper
@@ -15,7 +16,9 @@ interface IAssetsTableTagsPivotProps {
15
16
  addAssetTag: (api: any, id: string, tags: string) => any;
16
17
  deleteAssetTag: (api: any, id: string, tag: string) => any;
17
18
  onClose(e, row): void;
19
+ getAssetTagList: (api: any, storyId: string) => any;
18
20
  assetTags: string[];
21
+ project: any;
19
22
  }
20
23
 
21
24
  class AssetsTableTagsPivot extends React.PureComponent<IAssetsTableTagsPivotProps> {
@@ -29,7 +32,8 @@ class AssetsTableTagsPivot extends React.PureComponent<IAssetsTableTagsPivotProp
29
32
 
30
33
  private addTags = (assetId: string, tags: string): void => {
31
34
  const {
32
- row: { original }
35
+ row: { original },
36
+ project: { storyId }
33
37
  } = this.props;
34
38
 
35
39
  let newTags = tags.split(',');
@@ -42,6 +46,7 @@ class AssetsTableTagsPivot extends React.PureComponent<IAssetsTableTagsPivotProp
42
46
 
43
47
  if (newTags) {
44
48
  this.props.addAssetTag(this.props.api, assetId, newTags.join());
49
+ this.props.getAssetTagList(this.props.api, storyId);
45
50
  }
46
51
  };
47
52
 
@@ -52,6 +57,7 @@ class AssetsTableTagsPivot extends React.PureComponent<IAssetsTableTagsPivotProp
52
57
  },
53
58
  assetTags
54
59
  } = this.props;
60
+
55
61
  const tagsArray = [...new Set(tags)];
56
62
  const tagsMarkup: JSX.Element[] = tagsArray.map((tag: string) => (
57
63
  <Tag
@@ -91,12 +97,13 @@ class AssetsTableTagsPivot extends React.PureComponent<IAssetsTableTagsPivotProp
91
97
  }
92
98
 
93
99
  const mapDispatchToProps = (dispatch): any => {
94
- return bindActionCreators({ addAssetTag, deleteAssetTag }, dispatch);
100
+ return bindActionCreators({ addAssetTag, deleteAssetTag, getAssetTagList }, dispatch);
95
101
  };
96
102
 
97
103
  const mapStateToProps = (state): any => {
98
104
  return {
99
- assetTags: state.assetTags
105
+ assetTags: state.assetTags,
106
+ project: state.project
100
107
  };
101
108
  };
102
109
 
@@ -12,8 +12,8 @@ import {
12
12
  ICON_CLIPBOARD,
13
13
  ICON_TIMES
14
14
  } from '../../constants/icons';
15
-
16
- import Autosuggest from 'react-autosuggest';
15
+ import ReactTextareaAutocomplete from '@imposium-hub/react-textarea-autocomplete';
16
+ import Spinner from '../spinner/Spinner';
17
17
 
18
18
  interface ITextFieldProps {
19
19
  buttons?: any;
@@ -54,19 +54,17 @@ interface ITextFieldState {
54
54
  class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
55
55
  private inputRef: any;
56
56
 
57
+ private textAreaRef: any;
58
+
57
59
  private evtHandlers = {
58
- submittable: () => this.forceSubmit(),
60
+ submittable: (e) => this.forceSubmit(e),
59
61
  controlled: (e) => this.toggleEditing(e),
60
62
  cancel: () => this.cancelEdit(),
61
- clear: () => this.forceSubmit(true),
63
+ clear: (e) => this.forceSubmit(e, true),
62
64
  toggleEditing: (e) => this.toggleEditing(e),
63
- forceSubmit: () => this.forceSubmit(),
65
+ forceSubmit: (e) => this.forceSubmit(e),
64
66
  clearValue: () => this.clearValue(),
65
- copyToClipboard: (e) => this.copyToClipboard(e),
66
- onSuggestionsFetchRequested: (e) => this.onSuggestionsFetchRequested(e),
67
- onSuggestionsClearRequested: () => this.onSuggestionsClearRequested(),
68
- getSuggestionValue: (e) => this.getSuggestionValue(e),
69
- renderSuggestion: (e) => this.renderSuggestion(e)
67
+ copyToClipboard: (e) => this.copyToClipboard(e)
70
68
  };
71
69
 
72
70
  constructor(props) {
@@ -86,6 +84,8 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
86
84
 
87
85
  this.inputRef = React.createRef();
88
86
 
87
+ this.textAreaRef = React.createRef();
88
+
89
89
  hotkeys.filter = (e) => filterHotkeys(e);
90
90
  }
91
91
 
@@ -106,14 +106,25 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
106
106
  }
107
107
 
108
108
  public componentDidUpdate = (prevProps, prevState): void => {
109
- if (this.props.controlled || this.props.submittable) {
110
- if (prevProps.value !== this.props.value) {
109
+ const { controlled, submittable, value } = this.props;
110
+ const { editing, internalValue } = this.state;
111
+
112
+ if (submittable) {
113
+ this.textAreaRef.onkeydown = (e) => {
114
+ if (e.key === 'Enter') {
115
+ this.props.doSubmit(internalValue);
116
+ }
117
+ };
118
+ }
119
+
120
+ if (controlled || submittable) {
121
+ if (prevProps.value !== value) {
111
122
  this.setState({
112
- internalValue: this.props.value
123
+ internalValue: value
113
124
  });
114
125
  }
115
126
 
116
- if (this.props.value === '' && !this.state.editing && prevState.editing) {
127
+ if (value === '' && !editing && prevState.editing) {
117
128
  this.setState({
118
129
  internalValue: ''
119
130
  });
@@ -197,7 +208,6 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
197
208
  private onChange(e, v?) {
198
209
  const { pattern } = this.props;
199
210
  let val = v ? v.newValue : e.target.value;
200
-
201
211
  if (!this.props.controlled && !this.props.submittable) {
202
212
  if (pattern) {
203
213
  if (!pattern.test(val)) {
@@ -217,7 +227,7 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
217
227
  () => {
218
228
  if (v) {
219
229
  if (v.method === 'click') {
220
- this.evtHandlers.submittable();
230
+ this.evtHandlers.submittable(e);
221
231
  }
222
232
  }
223
233
  }
@@ -225,10 +235,11 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
225
235
  }
226
236
  }
227
237
 
228
- private forceSubmit = (clear: boolean = false): void => {
238
+ private forceSubmit = (e, clear: boolean = false): void => {
239
+ e.preventDefault();
229
240
  const { internalValue } = this.state;
230
241
 
231
- if (!clear) {
242
+ if (!clear && internalValue !== '') {
232
243
  this.props.doSubmit(internalValue);
233
244
 
234
245
  if (this.props.submittableType === 'add') {
@@ -242,6 +253,14 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
242
253
  }
243
254
  };
244
255
 
256
+ private onClickHandler = (e, value): void => {
257
+ e.preventDefault();
258
+ e.stopPropagation();
259
+
260
+ this.props.doSubmit(value);
261
+ this.setState({ internalValue: '' });
262
+ };
263
+
245
264
  private toggleEditing(e) {
246
265
  e.preventDefault();
247
266
  e.stopPropagation();
@@ -257,7 +276,7 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
257
276
  () => {
258
277
  // only fire onSubmit if the value changed
259
278
  if (internalValue !== value) {
260
- let val = this.state.internalValue;
279
+ let val = internalValue;
261
280
  if (val === '') {
262
281
  val = null;
263
282
  }
@@ -292,26 +311,6 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
292
311
  );
293
312
  }
294
313
 
295
- private getSuggestions(value) {
296
- const inputValue = value.trim().toLowerCase();
297
- const inputLength = inputValue.length;
298
-
299
- return inputLength === 0
300
- ? []
301
- : this.props.suggestions.filter(
302
- (tag) => tag.toLowerCase().slice(0, inputLength) === inputValue
303
- );
304
- }
305
-
306
- private getSuggestionValue(suggestion) {
307
- return suggestion;
308
- }
309
-
310
- // Use your imagination to render suggestions.
311
- private renderSuggestion(suggestion) {
312
- return <div className='suggestion'>{suggestion}</div>;
313
- }
314
-
315
314
  private renderSubmittableIcon = (): JSX.Element => {
316
315
  const { submittableType } = this.props;
317
316
 
@@ -404,21 +403,8 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
404
403
  return buttonArray;
405
404
  }
406
405
 
407
- private onSuggestionsFetchRequested = ({ value }) => {
408
- this.setState({
409
- suggestions: this.getSuggestions(value)
410
- });
411
- };
412
-
413
- private onSuggestionsClearRequested = () => {
414
- this.setState({
415
- suggestions: []
416
- });
417
- };
418
-
419
406
  private renderInput() {
420
407
  const { placeholder, controlled, submittable, disabled, readOnly, loading } = this.props;
421
- const { suggestions } = this.state;
422
408
  const { editing } = this.state;
423
409
  const disable = (controlled && !editing) || disabled;
424
410
  const inputClass = controlled || submittable ? 'controlled-input' : '';
@@ -431,25 +417,57 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
431
417
  readOnly,
432
418
  ref: this.inputRef,
433
419
  onFocus: (e) => this.focus(e),
434
- onBlur: (e) => this.blur(e)
420
+ onBlur: (e) => this.blur(e),
421
+ onChange: (e) => this.onChange(e)
435
422
  };
436
423
 
437
424
  if (this.props.suggestions) {
438
- inputProps.onChange = (e, v) => this.onChange(e, v);
425
+ const chars = [];
426
+ const varsData = [];
427
+ const trigger = {};
428
+
429
+ this.props.suggestions.map((tag) => {
430
+ chars.push(tag[0]);
431
+ const obj = {
432
+ name: `${tag}`
433
+ };
434
+ varsData.push(obj);
435
+ });
436
+
437
+ const variableItem = ({ entity: { name } }) => (
438
+ <div
439
+ className='variable'
440
+ onClick={(e) => this.onClickHandler(e, name)}>{`${name}`}</div>
441
+ );
442
+ const uniqueChars = [...new Set(chars)];
443
+
444
+ for (const char of uniqueChars) {
445
+ trigger[char] = {
446
+ dataProvider: () => {
447
+ const filtered = varsData.filter((f) =>
448
+ f.name.toLowerCase().startsWith(char)
449
+ );
450
+ return filtered;
451
+ },
452
+ component: variableItem,
453
+ output: (tag) => `${tag.name}`
454
+ };
455
+ }
456
+
457
+ const value = this.getValue();
439
458
 
440
459
  return (
441
- <Autosuggest
442
- suggestions={suggestions}
443
- onSuggestionsFetchRequested={this.evtHandlers.onSuggestionsFetchRequested}
444
- onSuggestionsClearRequested={this.evtHandlers.onSuggestionsClearRequested}
445
- getSuggestionValue={this.evtHandlers.getSuggestionValue}
446
- renderSuggestion={this.evtHandlers.renderSuggestion}
447
- inputProps={inputProps}
460
+ <ReactTextareaAutocomplete
461
+ value={value}
462
+ loadingComponent={() => <Spinner />}
463
+ minChar={0}
464
+ textAreaComponent='input'
465
+ trigger={trigger}
466
+ innerRef={(ref) => (this.textAreaRef = ref)}
467
+ {...inputProps}
448
468
  />
449
469
  );
450
470
  } else {
451
- inputProps.onChange = (e) => this.onChange(e);
452
-
453
471
  return (
454
472
  <input
455
473
  className={`${inputClass}`}