@imposium-hub/components 1.58.4 → 1.58.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.
- package/dist/cjs/components/asset-details/AssetDetails.js +2 -0
- package/dist/cjs/components/asset-details/AssetDetails.js.map +1 -1
- package/dist/cjs/components/assets/AssetsTableTagsPivot.js +6 -3
- package/dist/cjs/components/assets/AssetsTableTagsPivot.js.map +1 -1
- package/dist/cjs/components/text-field/TextField.d.ts +2 -5
- package/dist/cjs/components/text-field/TextField.js +86 -48
- package/dist/cjs/components/text-field/TextField.js.map +1 -1
- package/dist/esm/components/asset-details/AssetDetails.js +2 -0
- package/dist/esm/components/asset-details/AssetDetails.js.map +1 -1
- package/dist/esm/components/assets/AssetsTableTagsPivot.js +6 -3
- package/dist/esm/components/assets/AssetsTableTagsPivot.js.map +1 -1
- package/dist/esm/components/text-field/TextField.d.ts +2 -5
- package/dist/esm/components/text-field/TextField.js +56 -46
- package/dist/esm/components/text-field/TextField.js.map +1 -1
- package/dist/styles.css +65 -30
- package/dist/styles.less +59 -56
- package/less/components/assets.less +58 -0
- package/less/components/form-field.less +1 -56
- package/package.json +4 -4
- package/src/components/asset-details/AssetDetails.tsx +10 -0
- package/src/components/assets/AssetsTableTagsPivot.tsx +10 -3
- package/src/components/text-field/TextField.tsx +79 -63
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imposium-hub/components",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.6",
|
|
4
4
|
"description": "React & Typescript component / asset library for Imposium front-ends",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -54,11 +54,11 @@
|
|
|
54
54
|
"@fortawesome/pro-light-svg-icons": "^6.1.1",
|
|
55
55
|
"@fortawesome/pro-solid-svg-icons": "^6.1.1",
|
|
56
56
|
"@fortawesome/react-fontawesome": "^0.1.18",
|
|
57
|
+
"@imposium-hub/react-textarea-autocomplete": "^4.9.5",
|
|
57
58
|
"axios": "^0.21.1",
|
|
58
59
|
"hotkeys-js": "^3.6.12",
|
|
59
60
|
"localforage": "^1.7.3",
|
|
60
61
|
"react": "^17.0.1",
|
|
61
|
-
"react-autosuggest": "^9.4.3",
|
|
62
62
|
"react-dnd": "^14.0.2",
|
|
63
63
|
"react-dnd-html5-backend": "^14.0.0",
|
|
64
64
|
"react-dom": "^17.0.2",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"@fortawesome/react-fontawesome": "^0.1.18",
|
|
81
81
|
"@imposium-hub/eslint-config": "^1.1.0",
|
|
82
82
|
"@imposium-hub/prettier-config": "^2.1.0",
|
|
83
|
+
"@imposium-hub/react-textarea-autocomplete": "^4.9.5",
|
|
83
84
|
"@storybook/addon-actions": "^6.4.22",
|
|
84
85
|
"@storybook/addon-docs": "^6.4.22",
|
|
85
86
|
"@storybook/addon-essentials": "^6.4.22",
|
|
@@ -110,7 +111,6 @@
|
|
|
110
111
|
"onchange": "^7.1.0",
|
|
111
112
|
"prettier": "^2.6.2",
|
|
112
113
|
"react": "^17.0.1",
|
|
113
|
-
"react-autosuggest": "^9.4.3",
|
|
114
114
|
"react-dnd": "^14.0.2",
|
|
115
115
|
"react-dnd-html5-backend": "^14.0.0",
|
|
116
116
|
"react-dom": "^17.0.2",
|
|
@@ -122,8 +122,8 @@
|
|
|
122
122
|
"react-tooltip": "3.11.1",
|
|
123
123
|
"run-sequence": "^2.2.1",
|
|
124
124
|
"sb": "^6.4.22",
|
|
125
|
-
"storybook-dark-mode": "^1.1.0",
|
|
126
125
|
"smpte-timecode": "^1.2.3",
|
|
126
|
+
"storybook-dark-mode": "^1.1.0",
|
|
127
127
|
"typescript": "^4.6.3"
|
|
128
128
|
},
|
|
129
129
|
"eslintConfig": {
|
|
@@ -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
|
|
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,23 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
public componentDidUpdate = (prevProps, prevState): void => {
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
const { controlled, submittable, value } = this.props;
|
|
110
|
+
const { editing, internalValue } = this.state;
|
|
111
|
+
|
|
112
|
+
if (controlled || submittable) {
|
|
113
|
+
this.textAreaRef.onkeydown = (e) => {
|
|
114
|
+
if (e.key === 'Enter') {
|
|
115
|
+
this.props.doSubmit(internalValue);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
if (prevProps.value !== value) {
|
|
111
120
|
this.setState({
|
|
112
|
-
internalValue:
|
|
121
|
+
internalValue: value
|
|
113
122
|
});
|
|
114
123
|
}
|
|
115
124
|
|
|
116
|
-
if (
|
|
125
|
+
if (value === '' && !editing && prevState.editing) {
|
|
117
126
|
this.setState({
|
|
118
127
|
internalValue: ''
|
|
119
128
|
});
|
|
@@ -197,7 +206,6 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
197
206
|
private onChange(e, v?) {
|
|
198
207
|
const { pattern } = this.props;
|
|
199
208
|
let val = v ? v.newValue : e.target.value;
|
|
200
|
-
|
|
201
209
|
if (!this.props.controlled && !this.props.submittable) {
|
|
202
210
|
if (pattern) {
|
|
203
211
|
if (!pattern.test(val)) {
|
|
@@ -217,7 +225,7 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
217
225
|
() => {
|
|
218
226
|
if (v) {
|
|
219
227
|
if (v.method === 'click') {
|
|
220
|
-
this.evtHandlers.submittable();
|
|
228
|
+
this.evtHandlers.submittable(e);
|
|
221
229
|
}
|
|
222
230
|
}
|
|
223
231
|
}
|
|
@@ -225,10 +233,11 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
225
233
|
}
|
|
226
234
|
}
|
|
227
235
|
|
|
228
|
-
private forceSubmit = (clear: boolean = false): void => {
|
|
236
|
+
private forceSubmit = (e, clear: boolean = false): void => {
|
|
237
|
+
e.preventDefault();
|
|
229
238
|
const { internalValue } = this.state;
|
|
230
239
|
|
|
231
|
-
if (!clear) {
|
|
240
|
+
if (!clear && internalValue !== '') {
|
|
232
241
|
this.props.doSubmit(internalValue);
|
|
233
242
|
|
|
234
243
|
if (this.props.submittableType === 'add') {
|
|
@@ -242,6 +251,14 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
242
251
|
}
|
|
243
252
|
};
|
|
244
253
|
|
|
254
|
+
private onClickHandler = (e, value): void => {
|
|
255
|
+
e.preventDefault();
|
|
256
|
+
e.stopPropagation();
|
|
257
|
+
|
|
258
|
+
this.props.doSubmit(value);
|
|
259
|
+
this.setState({ internalValue: '' });
|
|
260
|
+
};
|
|
261
|
+
|
|
245
262
|
private toggleEditing(e) {
|
|
246
263
|
e.preventDefault();
|
|
247
264
|
e.stopPropagation();
|
|
@@ -257,7 +274,7 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
257
274
|
() => {
|
|
258
275
|
// only fire onSubmit if the value changed
|
|
259
276
|
if (internalValue !== value) {
|
|
260
|
-
let val =
|
|
277
|
+
let val = internalValue;
|
|
261
278
|
if (val === '') {
|
|
262
279
|
val = null;
|
|
263
280
|
}
|
|
@@ -292,26 +309,6 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
292
309
|
);
|
|
293
310
|
}
|
|
294
311
|
|
|
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
312
|
private renderSubmittableIcon = (): JSX.Element => {
|
|
316
313
|
const { submittableType } = this.props;
|
|
317
314
|
|
|
@@ -404,21 +401,8 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
404
401
|
return buttonArray;
|
|
405
402
|
}
|
|
406
403
|
|
|
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
404
|
private renderInput() {
|
|
420
405
|
const { placeholder, controlled, submittable, disabled, readOnly, loading } = this.props;
|
|
421
|
-
const { suggestions } = this.state;
|
|
422
406
|
const { editing } = this.state;
|
|
423
407
|
const disable = (controlled && !editing) || disabled;
|
|
424
408
|
const inputClass = controlled || submittable ? 'controlled-input' : '';
|
|
@@ -431,25 +415,57 @@ class TextField extends React.PureComponent<ITextFieldProps, ITextFieldState> {
|
|
|
431
415
|
readOnly,
|
|
432
416
|
ref: this.inputRef,
|
|
433
417
|
onFocus: (e) => this.focus(e),
|
|
434
|
-
onBlur: (e) => this.blur(e)
|
|
418
|
+
onBlur: (e) => this.blur(e),
|
|
419
|
+
onChange: (e) => this.onChange(e)
|
|
435
420
|
};
|
|
436
421
|
|
|
437
422
|
if (this.props.suggestions) {
|
|
438
|
-
|
|
423
|
+
const chars = [];
|
|
424
|
+
const varsData = [];
|
|
425
|
+
const trigger = {};
|
|
426
|
+
|
|
427
|
+
this.props.suggestions.map((tag) => {
|
|
428
|
+
chars.push(tag[0]);
|
|
429
|
+
const obj = {
|
|
430
|
+
name: `${tag}`
|
|
431
|
+
};
|
|
432
|
+
varsData.push(obj);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
const variableItem = ({ entity: { name } }) => (
|
|
436
|
+
<div
|
|
437
|
+
className='variable'
|
|
438
|
+
onClick={(e) => this.onClickHandler(e, name)}>{`${name}`}</div>
|
|
439
|
+
);
|
|
440
|
+
const uniqueChars = [...new Set(chars)];
|
|
441
|
+
|
|
442
|
+
for (const char of uniqueChars) {
|
|
443
|
+
trigger[char] = {
|
|
444
|
+
dataProvider: () => {
|
|
445
|
+
const filtered = varsData.filter((f) =>
|
|
446
|
+
f.name.toLowerCase().startsWith(char)
|
|
447
|
+
);
|
|
448
|
+
return filtered;
|
|
449
|
+
},
|
|
450
|
+
component: variableItem,
|
|
451
|
+
output: (tag) => `${tag.name}`
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const value = this.getValue();
|
|
439
456
|
|
|
440
457
|
return (
|
|
441
|
-
<
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
458
|
+
<ReactTextareaAutocomplete
|
|
459
|
+
value={value}
|
|
460
|
+
loadingComponent={() => <Spinner />}
|
|
461
|
+
minChar={0}
|
|
462
|
+
textAreaComponent='input'
|
|
463
|
+
trigger={trigger}
|
|
464
|
+
innerRef={(ref) => (this.textAreaRef = ref)}
|
|
465
|
+
{...inputProps}
|
|
448
466
|
/>
|
|
449
467
|
);
|
|
450
468
|
} else {
|
|
451
|
-
inputProps.onChange = (e) => this.onChange(e);
|
|
452
|
-
|
|
453
469
|
return (
|
|
454
470
|
<input
|
|
455
471
|
className={`${inputClass}`}
|