@guillotinaweb/react-gmi 0.29.0 → 0.29.2-alpha.2
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/components/index.d.ts +0 -2
- package/dist/components/input/email.d.ts +1 -1
- package/dist/components/selected_items_actions.d.ts +14 -0
- package/dist/index.d.ts +2 -0
- package/dist/react-gmi.esm.js +300 -193
- package/dist/react-gmi.esm.js.map +1 -1
- package/dist/react-gmi.js +300 -193
- package/dist/react-gmi.js.map +1 -1
- package/dist/react-gmi.modern.js +263 -155
- package/dist/react-gmi.modern.js.map +1 -1
- package/dist/react-gmi.umd.js +300 -193
- package/dist/react-gmi.umd.js.map +1 -1
- package/package.json +2 -2
- package/dist/lib/search.test.d.ts +0 -1
- package/dist/locales/generic_messages.d.ts +0 -370
- package/dist/setupTests.d.ts +0 -1
package/dist/react-gmi.modern.js
CHANGED
|
@@ -92,6 +92,7 @@ class Traversal {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
apply(data) {
|
|
95
|
+
// apply a optimistic update to context
|
|
95
96
|
this.dispatch({
|
|
96
97
|
type: 'APPLY',
|
|
97
98
|
payload: data
|
|
@@ -682,8 +683,10 @@ function base64ToArrayBuffer(base64) {
|
|
|
682
683
|
return bytes;
|
|
683
684
|
}
|
|
684
685
|
function stringToSlug(str) {
|
|
685
|
-
str = str.replace(/^\s+|\s+$/g, '');
|
|
686
|
-
|
|
686
|
+
str = str.replace(/^\s+|\s+$/g, ''); // trim
|
|
687
|
+
|
|
688
|
+
str = str.toLowerCase(); // remove accents, swap ñ for n, etc
|
|
689
|
+
|
|
687
690
|
const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';
|
|
688
691
|
const to = 'aaaaeeeeiiiioooouuuunc------';
|
|
689
692
|
|
|
@@ -691,7 +694,10 @@ function stringToSlug(str) {
|
|
|
691
694
|
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
|
|
692
695
|
}
|
|
693
696
|
|
|
694
|
-
str = str.replace(/[^a-z0-9 -]/g, '')
|
|
697
|
+
str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
|
|
698
|
+
.replace(/\s+/g, '-') // collapse whitespace and replace by -
|
|
699
|
+
.replace(/-+/g, '-'); // collapse dashes
|
|
700
|
+
|
|
695
701
|
return str;
|
|
696
702
|
}
|
|
697
703
|
function sleep(ms) {
|
|
@@ -814,7 +820,8 @@ function Confirm({
|
|
|
814
820
|
})]
|
|
815
821
|
})]
|
|
816
822
|
});
|
|
817
|
-
}
|
|
823
|
+
} // @todo Improve it... Replacing the inputText to a tree
|
|
824
|
+
|
|
818
825
|
function PathTree({
|
|
819
826
|
title,
|
|
820
827
|
defaultPath,
|
|
@@ -1062,6 +1069,7 @@ const Config = {
|
|
|
1062
1069
|
DelayActions: 200,
|
|
1063
1070
|
Permissions: Permissions,
|
|
1064
1071
|
SearchEngine: 'PostreSQL',
|
|
1072
|
+
// Elasticsearch
|
|
1065
1073
|
fieldHaveDeleteButton: schema => {
|
|
1066
1074
|
return (schema == null ? void 0 : schema.widget) === 'file' || (schema == null ? void 0 : schema.widget) === 'select' || (schema == null ? void 0 : schema.type) === 'array';
|
|
1067
1075
|
}
|
|
@@ -1113,7 +1121,9 @@ function RemoveItems(props) {
|
|
|
1113
1121
|
const err = await res.json();
|
|
1114
1122
|
errors.push(err);
|
|
1115
1123
|
}
|
|
1116
|
-
});
|
|
1124
|
+
}); // this sleep is here, to let elasticsearch, wait for
|
|
1125
|
+
// index our operations... (will work 99% of use cases)
|
|
1126
|
+
|
|
1117
1127
|
actions.push(sleep(cfg.DelayActions));
|
|
1118
1128
|
await Promise.all(actions);
|
|
1119
1129
|
|
|
@@ -1257,6 +1267,9 @@ const useInput = (onChange, value, validator) => {
|
|
|
1257
1267
|
};
|
|
1258
1268
|
};
|
|
1259
1269
|
|
|
1270
|
+
// From github.com/protonmail/proton-shared
|
|
1271
|
+
|
|
1272
|
+
/* eslint-disable no-useless-escape */
|
|
1260
1273
|
const REGEX_EMAIL = /(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/i;
|
|
1261
1274
|
const REGEX_URL = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/;
|
|
1262
1275
|
const REGEX_HEX_COLOR = /^#([a-f0-9]{3,4}|[a-f0-9]{4}(?:[a-f0-9]{2}){1,2})\b$/i;
|
|
@@ -1307,7 +1320,8 @@ const Input = forwardRef(({
|
|
|
1307
1320
|
handlers = _objectWithoutPropertiesLoose(_useInput, ["state"]);
|
|
1308
1321
|
|
|
1309
1322
|
const [uid] = useState(generateUID('input'));
|
|
1310
|
-
const [mounted, setMounted] = useState(false);
|
|
1323
|
+
const [mounted, setMounted] = useState(false); // eslint-disable-next-line
|
|
1324
|
+
|
|
1311
1325
|
ref = ref || useRef();
|
|
1312
1326
|
useEffect(() => {
|
|
1313
1327
|
setMounted(true);
|
|
@@ -1372,7 +1386,8 @@ const EmailInput = ({
|
|
|
1372
1386
|
value: _value = '',
|
|
1373
1387
|
dataTest,
|
|
1374
1388
|
placeholder,
|
|
1375
|
-
id
|
|
1389
|
+
id,
|
|
1390
|
+
onChange
|
|
1376
1391
|
}) => {
|
|
1377
1392
|
const intl = useIntl();
|
|
1378
1393
|
return jsx(Input, {
|
|
@@ -1391,7 +1406,8 @@ const EmailInput = ({
|
|
|
1391
1406
|
icon: "fas fa-envelope"
|
|
1392
1407
|
}),
|
|
1393
1408
|
id: id,
|
|
1394
|
-
placeholder: placeholder
|
|
1409
|
+
placeholder: placeholder,
|
|
1410
|
+
onChange: onChange
|
|
1395
1411
|
});
|
|
1396
1412
|
};
|
|
1397
1413
|
|
|
@@ -1466,17 +1482,19 @@ function FormBuilder({
|
|
|
1466
1482
|
properties,
|
|
1467
1483
|
required
|
|
1468
1484
|
} = schema;
|
|
1469
|
-
const values = Object.assign({}, formData || {});
|
|
1485
|
+
const values = Object.assign({}, formData || {}); // build initial state
|
|
1486
|
+
|
|
1470
1487
|
const initialState = {};
|
|
1471
1488
|
const fields = Object.keys(properties).filter(x => !exclude.includes(x));
|
|
1472
1489
|
fields.forEach(element => {
|
|
1473
1490
|
initialState[element] = values[element] || undefined;
|
|
1474
|
-
});
|
|
1491
|
+
}); // Register remotes
|
|
1475
1492
|
|
|
1476
1493
|
if (!ref.current) {
|
|
1477
1494
|
ref.current = {};
|
|
1478
1495
|
Object.keys(remotes).forEach(item => ref.current[item] = remotes[item]);
|
|
1479
1496
|
} else {
|
|
1497
|
+
// apply remote changes
|
|
1480
1498
|
Object.keys(remotes).forEach(key => {
|
|
1481
1499
|
if (JSON.stringify(ref.current[key]) !== JSON.stringify(remotes[key])) {
|
|
1482
1500
|
ref.current[key] = remotes[key];
|
|
@@ -1621,128 +1639,7 @@ const Select = forwardRef(({
|
|
|
1621
1639
|
});
|
|
1622
1640
|
Select.displayName = 'Select';
|
|
1623
1641
|
|
|
1624
|
-
|
|
1625
|
-
const d = new Date(str);
|
|
1626
|
-
const minutes = d.getMinutes() < 10 ? `0${d.getMinutes()}` : d.getMinutes();
|
|
1627
|
-
return `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()} ${d.getHours()}:${minutes}`;
|
|
1628
|
-
};
|
|
1629
|
-
const get$1 = (obj, path, defValue) => {
|
|
1630
|
-
var _pathArray$reduce;
|
|
1631
|
-
|
|
1632
|
-
if (!path) return undefined;
|
|
1633
|
-
const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
|
|
1634
|
-
return (_pathArray$reduce = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj)) != null ? _pathArray$reduce : defValue;
|
|
1635
|
-
};
|
|
1636
|
-
function getNewId(id = '') {
|
|
1637
|
-
const suffix = '-copy-';
|
|
1638
|
-
const rgx = new RegExp(`($|${suffix}\\d*)`);
|
|
1639
|
-
return stringToSlug(id).replace(rgx, r => {
|
|
1640
|
-
const num = parseInt(r.replace(suffix, '') || '0');
|
|
1641
|
-
return `${suffix}${num + 1}`;
|
|
1642
|
-
});
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
function useVocabulary(vocabularyName, path = null) {
|
|
1646
|
-
const traversal = useTraversal();
|
|
1647
|
-
const [vocabulary, setVocabulary] = useSetState({
|
|
1648
|
-
data: undefined,
|
|
1649
|
-
loading: false,
|
|
1650
|
-
error: undefined
|
|
1651
|
-
});
|
|
1652
|
-
|
|
1653
|
-
const getPath = () => {
|
|
1654
|
-
if (path) return path;
|
|
1655
|
-
return `${traversal.path}@vocabularies/${vocabularyName}`;
|
|
1656
|
-
};
|
|
1657
|
-
|
|
1658
|
-
useEffect(() => {
|
|
1659
|
-
const getVocabulary = async () => {
|
|
1660
|
-
if (vocabularyName && vocabulary.data === undefined && !vocabulary.loading) {
|
|
1661
|
-
try {
|
|
1662
|
-
setVocabulary({
|
|
1663
|
-
loading: true
|
|
1664
|
-
});
|
|
1665
|
-
const data = await traversal.client.get(getPath());
|
|
1666
|
-
const dataJson = await data.json();
|
|
1667
|
-
setVocabulary({
|
|
1668
|
-
loading: false,
|
|
1669
|
-
data: dataJson
|
|
1670
|
-
});
|
|
1671
|
-
} catch (err) {
|
|
1672
|
-
setVocabulary({
|
|
1673
|
-
loading: false,
|
|
1674
|
-
error: err,
|
|
1675
|
-
data: undefined
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
}
|
|
1679
|
-
};
|
|
1680
|
-
|
|
1681
|
-
getVocabulary();
|
|
1682
|
-
}, [vocabularyName, vocabulary, path]);
|
|
1683
|
-
return vocabulary;
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
const SelectVocabulary = forwardRef(({
|
|
1687
|
-
vocabularyName,
|
|
1688
|
-
className,
|
|
1689
|
-
classWrap,
|
|
1690
|
-
val,
|
|
1691
|
-
dataTest,
|
|
1692
|
-
multiple,
|
|
1693
|
-
onChange,
|
|
1694
|
-
id,
|
|
1695
|
-
placeholder
|
|
1696
|
-
}, ref) => {
|
|
1697
|
-
const vocabulary = useVocabulary(vocabularyName);
|
|
1698
|
-
|
|
1699
|
-
const getOptions = () => {
|
|
1700
|
-
if (get$1(vocabulary, 'data.items', null)) {
|
|
1701
|
-
const vocData = vocabulary.data.items.map(item => {
|
|
1702
|
-
return {
|
|
1703
|
-
text: item.title,
|
|
1704
|
-
value: item.token
|
|
1705
|
-
};
|
|
1706
|
-
});
|
|
1707
|
-
return vocData;
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
return [];
|
|
1711
|
-
};
|
|
1712
|
-
|
|
1713
|
-
const getProps = () => {
|
|
1714
|
-
if (multiple) {
|
|
1715
|
-
const currentValue = val || [];
|
|
1716
|
-
return {
|
|
1717
|
-
multiple: true,
|
|
1718
|
-
size: 5,
|
|
1719
|
-
value: currentValue,
|
|
1720
|
-
options: getOptions()
|
|
1721
|
-
};
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
return {
|
|
1725
|
-
value: val != null ? val : '',
|
|
1726
|
-
appendDefault: true,
|
|
1727
|
-
options: getOptions()
|
|
1728
|
-
};
|
|
1729
|
-
};
|
|
1730
|
-
|
|
1731
|
-
if (vocabulary.data === undefined || vocabulary.loading) {
|
|
1732
|
-
return jsx("div", {});
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
return jsx(Select, _extends({}, getProps(), {
|
|
1736
|
-
className: className,
|
|
1737
|
-
classWrap: classWrap || 'is-fullwidth',
|
|
1738
|
-
dataTest: dataTest,
|
|
1739
|
-
ref: ref,
|
|
1740
|
-
onChange: onChange,
|
|
1741
|
-
id: id,
|
|
1742
|
-
placeholder: placeholder
|
|
1743
|
-
}));
|
|
1744
|
-
});
|
|
1745
|
-
SelectVocabulary.displayName = 'SelectVocabulary';
|
|
1642
|
+
// https://github.com/molefrog/wouter
|
|
1746
1643
|
|
|
1747
1644
|
const setURLParams = p => {
|
|
1748
1645
|
return window.history.pushState(0, '0', '' + '?' + p.toString().replace(/%2F/g, '/'));
|
|
@@ -1758,7 +1655,10 @@ const useLocation = () => {
|
|
|
1758
1655
|
const [path, update] = useState(currentSearchParams());
|
|
1759
1656
|
const prevPath = useRef(path);
|
|
1760
1657
|
useEffect(() => {
|
|
1761
|
-
patchHistoryEvents();
|
|
1658
|
+
patchHistoryEvents(); // this function checks if the location has been changed since the
|
|
1659
|
+
// last render and updates the state only when needed.
|
|
1660
|
+
// unfortunately, we can't rely on `path` value here, since it can be stale,
|
|
1661
|
+
// that's why we store the last pathname in a ref.
|
|
1762
1662
|
|
|
1763
1663
|
const checkForUpdates = () => {
|
|
1764
1664
|
const pathname = currentSearchParams();
|
|
@@ -1766,12 +1666,20 @@ const useLocation = () => {
|
|
|
1766
1666
|
};
|
|
1767
1667
|
|
|
1768
1668
|
const events = ['popstate', 'pushState', 'replaceState'];
|
|
1769
|
-
events.map(e => window.addEventListener(e, checkForUpdates));
|
|
1669
|
+
events.map(e => window.addEventListener(e, checkForUpdates)); // it's possible that an update has occurred between render and the effect handler,
|
|
1670
|
+
// so we run additional check on mount to catch these updates. Based on:
|
|
1671
|
+
// https://gist.github.com/bvaughn/e25397f70e8c65b0ae0d7c90b731b189
|
|
1672
|
+
|
|
1770
1673
|
checkForUpdates();
|
|
1771
1674
|
return () => {
|
|
1772
1675
|
events.map(e => window.removeEventListener(e, checkForUpdates));
|
|
1773
1676
|
};
|
|
1774
|
-
}, []);
|
|
1677
|
+
}, []); // the 2nd argument of the `useLocation` return value is a function
|
|
1678
|
+
// that allows to perform a navigation.
|
|
1679
|
+
//
|
|
1680
|
+
// the function reference should stay the same between re-renders, so that
|
|
1681
|
+
// it can be passed down as an element prop without any performance concerns.
|
|
1682
|
+
|
|
1775
1683
|
const navigate = useCallback((to, replace) => {
|
|
1776
1684
|
if (replace) {
|
|
1777
1685
|
clean(to);
|
|
@@ -1788,7 +1696,12 @@ const useLocation = () => {
|
|
|
1788
1696
|
setURLParams(current);
|
|
1789
1697
|
}, [path]);
|
|
1790
1698
|
return [path, navigate, remove];
|
|
1791
|
-
};
|
|
1699
|
+
}; // While History API does have `popstate` event, the only
|
|
1700
|
+
// proper way to listen to changes via `push/replaceState`
|
|
1701
|
+
// is to monkey-patch these methods.
|
|
1702
|
+
//
|
|
1703
|
+
// See https://stackoverflow.com/a/4585031
|
|
1704
|
+
|
|
1792
1705
|
let patched = 0;
|
|
1793
1706
|
|
|
1794
1707
|
const patchHistoryEvents = () => {
|
|
@@ -1797,7 +1710,8 @@ const patchHistoryEvents = () => {
|
|
|
1797
1710
|
const original = window.history[type];
|
|
1798
1711
|
|
|
1799
1712
|
window.history[type] = function (...args) {
|
|
1800
|
-
const result = original.apply(this, args);
|
|
1713
|
+
const result = original.apply(this, args); // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1714
|
+
|
|
1801
1715
|
const event = new Event(type);
|
|
1802
1716
|
event.arguments = args;
|
|
1803
1717
|
dispatchEvent(event);
|
|
@@ -2232,7 +2146,8 @@ class GuillotinaClient {
|
|
|
2232
2146
|
children: m.updated
|
|
2233
2147
|
})
|
|
2234
2148
|
}];
|
|
2235
|
-
}
|
|
2149
|
+
} // BBB API changes. Compat G5 and G6
|
|
2150
|
+
|
|
2236
2151
|
|
|
2237
2152
|
applyCompat(data) {
|
|
2238
2153
|
data.member = data.items;
|
|
@@ -2320,7 +2235,8 @@ class GuillotinaClient {
|
|
|
2320
2235
|
|
|
2321
2236
|
async getTypeSchema(path, name) {
|
|
2322
2237
|
if (!cacheSchemas[name]) {
|
|
2323
|
-
const url = this.getContainerFromPath(path);
|
|
2238
|
+
const url = this.getContainerFromPath(path); // todo: handle db case (only addable containers)
|
|
2239
|
+
|
|
2324
2240
|
const res = await this.rest.get(`${url}@types/${name}`);
|
|
2325
2241
|
cacheSchemas[name] = await res.json();
|
|
2326
2242
|
}
|
|
@@ -2370,6 +2286,7 @@ class GuillotinaClient {
|
|
|
2370
2286
|
}
|
|
2371
2287
|
|
|
2372
2288
|
async getAllPermissions(path) {
|
|
2289
|
+
// paths used to query the API always has to start without a "/"
|
|
2373
2290
|
if (path.startsWith('/')) {
|
|
2374
2291
|
path = path.slice(1);
|
|
2375
2292
|
}
|
|
@@ -2554,10 +2471,37 @@ function useClickAway(ref, onClickAway, events = defaultEvents) {
|
|
|
2554
2471
|
}, [events, ref]);
|
|
2555
2472
|
}
|
|
2556
2473
|
|
|
2474
|
+
const formatDate = str => {
|
|
2475
|
+
const d = new Date(str);
|
|
2476
|
+
const minutes = d.getMinutes() < 10 ? `0${d.getMinutes()}` : d.getMinutes();
|
|
2477
|
+
return `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()} ${d.getHours()}:${minutes}`;
|
|
2478
|
+
};
|
|
2479
|
+
const get$1 = (obj, path, defValue) => {
|
|
2480
|
+
var _pathArray$reduce;
|
|
2481
|
+
|
|
2482
|
+
// If path is not defined or it has false value
|
|
2483
|
+
if (!path) return undefined; // Check if path is string or array. Regex : ensure that we do not have '.' and brackets.
|
|
2484
|
+
// Regex explained: https://regexr.com/58j0k
|
|
2485
|
+
|
|
2486
|
+
const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g); // Find value if exist return otherwise return undefined value;
|
|
2487
|
+
|
|
2488
|
+
return (_pathArray$reduce = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj)) != null ? _pathArray$reduce : defValue;
|
|
2489
|
+
};
|
|
2490
|
+
function getNewId(id = '') {
|
|
2491
|
+
const suffix = '-copy-';
|
|
2492
|
+
const rgx = new RegExp(`($|${suffix}\\d*)`);
|
|
2493
|
+
return stringToSlug(id).replace(rgx, r => {
|
|
2494
|
+
const num = parseInt(r.replace(suffix, '') || '0');
|
|
2495
|
+
return `${suffix}${num + 1}`;
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2557
2499
|
function debounce(func, wait) {
|
|
2558
2500
|
let timeout;
|
|
2559
2501
|
return function () {
|
|
2560
|
-
|
|
2502
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2503
|
+
const context = this; // eslint-disable-next-line prefer-rest-params
|
|
2504
|
+
|
|
2561
2505
|
const args = arguments;
|
|
2562
2506
|
|
|
2563
2507
|
const later = function later() {
|
|
@@ -2838,7 +2782,9 @@ const SearchInput = ({
|
|
|
2838
2782
|
function debounce$1(func, wait) {
|
|
2839
2783
|
let timeout;
|
|
2840
2784
|
return function () {
|
|
2841
|
-
|
|
2785
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2786
|
+
const context = this; // eslint-disable-next-line prefer-rest-params
|
|
2787
|
+
|
|
2842
2788
|
const args = arguments;
|
|
2843
2789
|
|
|
2844
2790
|
const later = function later() {
|
|
@@ -3433,7 +3379,8 @@ const DownloadField = ({
|
|
|
3433
3379
|
const blob = new Blob([text], {
|
|
3434
3380
|
type: data.content_type
|
|
3435
3381
|
});
|
|
3436
|
-
const url = window.URL.createObjectURL(blob);
|
|
3382
|
+
const url = window.URL.createObjectURL(blob); // Create blob link to download
|
|
3383
|
+
|
|
3437
3384
|
const link = document.createElement('a');
|
|
3438
3385
|
link.href = url;
|
|
3439
3386
|
|
|
@@ -3448,6 +3395,7 @@ const DownloadField = ({
|
|
|
3448
3395
|
setTimeout(function () {
|
|
3449
3396
|
var _link$parentNode;
|
|
3450
3397
|
|
|
3398
|
+
// For Firefox it is necessary to delay revoking the ObjectURL
|
|
3451
3399
|
window.URL.revokeObjectURL(url);
|
|
3452
3400
|
(_link$parentNode = link.parentNode) == null ? void 0 : _link$parentNode.removeChild(link);
|
|
3453
3401
|
}, 100);
|
|
@@ -3487,6 +3435,47 @@ const DownloadField = ({
|
|
|
3487
3435
|
});
|
|
3488
3436
|
};
|
|
3489
3437
|
|
|
3438
|
+
function useVocabulary(vocabularyName, path = null) {
|
|
3439
|
+
const traversal = useTraversal();
|
|
3440
|
+
const [vocabulary, setVocabulary] = useSetState({
|
|
3441
|
+
data: undefined,
|
|
3442
|
+
loading: false,
|
|
3443
|
+
error: undefined
|
|
3444
|
+
});
|
|
3445
|
+
|
|
3446
|
+
const getPath = () => {
|
|
3447
|
+
if (path) return path;
|
|
3448
|
+
return `${traversal.path}@vocabularies/${vocabularyName}`;
|
|
3449
|
+
};
|
|
3450
|
+
|
|
3451
|
+
useEffect(() => {
|
|
3452
|
+
const getVocabulary = async () => {
|
|
3453
|
+
if (vocabularyName && vocabulary.data === undefined && !vocabulary.loading) {
|
|
3454
|
+
try {
|
|
3455
|
+
setVocabulary({
|
|
3456
|
+
loading: true
|
|
3457
|
+
});
|
|
3458
|
+
const data = await traversal.client.get(getPath());
|
|
3459
|
+
const dataJson = await data.json();
|
|
3460
|
+
setVocabulary({
|
|
3461
|
+
loading: false,
|
|
3462
|
+
data: dataJson
|
|
3463
|
+
});
|
|
3464
|
+
} catch (err) {
|
|
3465
|
+
setVocabulary({
|
|
3466
|
+
loading: false,
|
|
3467
|
+
error: err,
|
|
3468
|
+
data: undefined
|
|
3469
|
+
});
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
|
|
3474
|
+
getVocabulary();
|
|
3475
|
+
}, [vocabularyName, vocabulary, path]);
|
|
3476
|
+
return vocabulary;
|
|
3477
|
+
}
|
|
3478
|
+
|
|
3490
3479
|
const plain = ['string', 'number', 'boolean'];
|
|
3491
3480
|
function RenderField({
|
|
3492
3481
|
value,
|
|
@@ -3715,6 +3704,67 @@ function RenderFieldComponent({
|
|
|
3715
3704
|
return jsx(RenderField, _extends({}, getRenderProps()));
|
|
3716
3705
|
}
|
|
3717
3706
|
|
|
3707
|
+
const SelectVocabulary = forwardRef(({
|
|
3708
|
+
vocabularyName,
|
|
3709
|
+
className,
|
|
3710
|
+
classWrap,
|
|
3711
|
+
val,
|
|
3712
|
+
dataTest,
|
|
3713
|
+
multiple,
|
|
3714
|
+
onChange,
|
|
3715
|
+
id,
|
|
3716
|
+
placeholder
|
|
3717
|
+
}, ref) => {
|
|
3718
|
+
const vocabulary = useVocabulary(vocabularyName);
|
|
3719
|
+
|
|
3720
|
+
const getOptions = () => {
|
|
3721
|
+
if (get$1(vocabulary, 'data.items', null)) {
|
|
3722
|
+
const vocData = vocabulary.data.items.map(item => {
|
|
3723
|
+
return {
|
|
3724
|
+
text: item.title,
|
|
3725
|
+
value: item.token
|
|
3726
|
+
};
|
|
3727
|
+
});
|
|
3728
|
+
return vocData;
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3731
|
+
return [];
|
|
3732
|
+
};
|
|
3733
|
+
|
|
3734
|
+
const getProps = () => {
|
|
3735
|
+
if (multiple) {
|
|
3736
|
+
const currentValue = val || [];
|
|
3737
|
+
return {
|
|
3738
|
+
multiple: true,
|
|
3739
|
+
size: 5,
|
|
3740
|
+
value: currentValue,
|
|
3741
|
+
options: getOptions()
|
|
3742
|
+
};
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3745
|
+
return {
|
|
3746
|
+
value: val != null ? val : '',
|
|
3747
|
+
appendDefault: true,
|
|
3748
|
+
options: getOptions()
|
|
3749
|
+
};
|
|
3750
|
+
};
|
|
3751
|
+
|
|
3752
|
+
if (vocabulary.data === undefined || vocabulary.loading) {
|
|
3753
|
+
return jsx("div", {});
|
|
3754
|
+
}
|
|
3755
|
+
|
|
3756
|
+
return jsx(Select, _extends({}, getProps(), {
|
|
3757
|
+
className: className,
|
|
3758
|
+
classWrap: classWrap || 'is-fullwidth',
|
|
3759
|
+
dataTest: dataTest,
|
|
3760
|
+
ref: ref,
|
|
3761
|
+
onChange: onChange,
|
|
3762
|
+
id: id,
|
|
3763
|
+
placeholder: placeholder
|
|
3764
|
+
}));
|
|
3765
|
+
});
|
|
3766
|
+
SelectVocabulary.displayName = 'SelectVocabulary';
|
|
3767
|
+
|
|
3718
3768
|
const EditComponent = forwardRef(({
|
|
3719
3769
|
schema,
|
|
3720
3770
|
val,
|
|
@@ -4680,6 +4730,7 @@ class ItemModel {
|
|
|
4680
4730
|
}
|
|
4681
4731
|
|
|
4682
4732
|
get path() {
|
|
4733
|
+
// Compat
|
|
4683
4734
|
const item = this.item['@id'] ? this.item['@id'] : this.item['@absolute_url'];
|
|
4684
4735
|
let path = item.split('//')[1].split('/').splice(1).join('/');
|
|
4685
4736
|
path = `/${path}/`;
|
|
@@ -4700,6 +4751,7 @@ class ItemModel {
|
|
|
4700
4751
|
}
|
|
4701
4752
|
|
|
4702
4753
|
get icon() {
|
|
4754
|
+
// eslint-disable-next-line
|
|
4703
4755
|
const cfg = useConfig();
|
|
4704
4756
|
|
|
4705
4757
|
if (cfg.icons && cfg.icons[this.type]) {
|
|
@@ -4964,7 +5016,8 @@ const messages$2 = defineMessages({
|
|
|
4964
5016
|
"value": "Installed Addons"
|
|
4965
5017
|
}]
|
|
4966
5018
|
}
|
|
4967
|
-
});
|
|
5019
|
+
}); // TODO: Refactor without useAsync... just crudContext
|
|
5020
|
+
|
|
4968
5021
|
function PanelAddons() {
|
|
4969
5022
|
var _state$data$available, _state$data, _state$data$available2, _state$data2, _state$data$installed, _state$data3, _state$data$installed2, _state$data4;
|
|
4970
5023
|
|
|
@@ -5243,6 +5296,11 @@ function ItemsActionsProvider({
|
|
|
5243
5296
|
children: children
|
|
5244
5297
|
});
|
|
5245
5298
|
}
|
|
5299
|
+
/**
|
|
5300
|
+
* Checkbox component without props that consume the ItemsActionsContext
|
|
5301
|
+
* and it select/unselect all items of the page.
|
|
5302
|
+
*/
|
|
5303
|
+
|
|
5246
5304
|
function AllItemsCheckbox({
|
|
5247
5305
|
dataTest
|
|
5248
5306
|
}) {
|
|
@@ -5272,6 +5330,10 @@ function ItemCheckbox({
|
|
|
5272
5330
|
dataTest: dataTest
|
|
5273
5331
|
});
|
|
5274
5332
|
}
|
|
5333
|
+
/**
|
|
5334
|
+
* Dropdown to choose some action to apply to the selected items.
|
|
5335
|
+
*/
|
|
5336
|
+
|
|
5275
5337
|
function ItemsActionsDropdown() {
|
|
5276
5338
|
const intl = useIntl();
|
|
5277
5339
|
const ACTIONS_OBJECT = getActionsObject(intl, true);
|
|
@@ -5355,6 +5417,7 @@ function Pagination({
|
|
|
5355
5417
|
"aria-label": "pagination",
|
|
5356
5418
|
children: [jsx("a", {
|
|
5357
5419
|
className: "pagination-previous is-small",
|
|
5420
|
+
// disabled={current === 0}
|
|
5358
5421
|
onClick: () => current > 0 ? doPaginate(current - 1) : null,
|
|
5359
5422
|
children: jsx("span", {
|
|
5360
5423
|
className: "icon",
|
|
@@ -5364,6 +5427,7 @@ function Pagination({
|
|
|
5364
5427
|
})
|
|
5365
5428
|
}), jsx("a", {
|
|
5366
5429
|
className: "pagination-next is-small",
|
|
5430
|
+
// disabled={current >= maxPages - 1}
|
|
5367
5431
|
onClick: () => doPaginate(current + 1),
|
|
5368
5432
|
children: jsx("span", {
|
|
5369
5433
|
className: "icon",
|
|
@@ -5676,7 +5740,7 @@ function PanelItems() {
|
|
|
5676
5740
|
key: 'id',
|
|
5677
5741
|
direction: 'des'
|
|
5678
5742
|
});
|
|
5679
|
-
sortParsed = parser(`_sort_${defaultSortValue.direction}=${defaultSortValue.key}
|
|
5743
|
+
sortParsed = parser(`_sort_${defaultSortValue.direction}=${defaultSortValue.key}`);
|
|
5680
5744
|
}
|
|
5681
5745
|
|
|
5682
5746
|
const qsParsed = Ctx.client[fnName]({
|
|
@@ -5686,12 +5750,14 @@ function PanelItems() {
|
|
|
5686
5750
|
});
|
|
5687
5751
|
let qs = '';
|
|
5688
5752
|
|
|
5689
|
-
if (search || type ||
|
|
5753
|
+
if (search || type || resultQueryParams.length > 0) {
|
|
5690
5754
|
var _searchParsed, _typeParsed, _sortParsed;
|
|
5691
5755
|
|
|
5692
5756
|
qs = buildQs([...qsParsed, ...((_searchParsed = searchParsed) != null ? _searchParsed : []), ...((_typeParsed = typeParsed) != null ? _typeParsed : []), ...((_sortParsed = sortParsed) != null ? _sortParsed : []), ...resultQueryParams]);
|
|
5693
5757
|
} else {
|
|
5694
|
-
|
|
5758
|
+
var _sortParsed2;
|
|
5759
|
+
|
|
5760
|
+
qs = buildQs([...qsParsed, ...((_sortParsed2 = sortParsed) != null ? _sortParsed2 : [])]);
|
|
5695
5761
|
}
|
|
5696
5762
|
|
|
5697
5763
|
const {
|
|
@@ -6870,7 +6936,8 @@ function CreateButton() {
|
|
|
6870
6936
|
|
|
6871
6937
|
if (state.types && state.types.length === 0) {
|
|
6872
6938
|
return null;
|
|
6873
|
-
}
|
|
6939
|
+
} // Implement some kind of filtering
|
|
6940
|
+
|
|
6874
6941
|
|
|
6875
6942
|
return jsx(Dropdown, {
|
|
6876
6943
|
id: "dropdown-menu",
|
|
@@ -7021,12 +7088,17 @@ function TabsPanel({
|
|
|
7021
7088
|
} else {
|
|
7022
7089
|
currentTab = currentTab || Object.keys(tabs)[0];
|
|
7023
7090
|
}
|
|
7091
|
+
/*if (!Object.keys(tabs).includes(currentTab)) {
|
|
7092
|
+
setLocation(defaultTab)
|
|
7093
|
+
currentTab = defaultTab
|
|
7094
|
+
}*/
|
|
7095
|
+
|
|
7024
7096
|
|
|
7025
7097
|
const [current, setTab] = useState(currentTab);
|
|
7026
7098
|
const CurrentComp = tabs[current] || fallback;
|
|
7027
7099
|
React.useEffect(() => {
|
|
7028
7100
|
if (Object.keys(tabs).includes(currentTab)) {
|
|
7029
|
-
setTab(currentTab);
|
|
7101
|
+
setTab(currentTab); // setLocation({tab: currentTab})
|
|
7030
7102
|
}
|
|
7031
7103
|
}, [currentTab, tabs]);
|
|
7032
7104
|
|
|
@@ -7412,7 +7484,8 @@ function UsersToolbar() {
|
|
|
7412
7484
|
page: 0
|
|
7413
7485
|
});
|
|
7414
7486
|
ev.preventDefault();
|
|
7415
|
-
};
|
|
7487
|
+
}; // cleanup form on state.search change
|
|
7488
|
+
|
|
7416
7489
|
|
|
7417
7490
|
useEffect(() => {
|
|
7418
7491
|
if (!searchText || searchText === '') {
|
|
@@ -8057,7 +8130,8 @@ function GroupToolbar() {
|
|
|
8057
8130
|
page: 0
|
|
8058
8131
|
});
|
|
8059
8132
|
ev.preventDefault();
|
|
8060
|
-
};
|
|
8133
|
+
}; // cleanup form on state.search change
|
|
8134
|
+
|
|
8061
8135
|
|
|
8062
8136
|
useEffect(() => {
|
|
8063
8137
|
if (!searchText || searchText === '') {
|
|
@@ -8601,11 +8675,13 @@ const get$2 = (key, param, fallback = undefined) => {
|
|
|
8601
8675
|
};
|
|
8602
8676
|
|
|
8603
8677
|
const getComponent = (context, path, fallback = undefined) => {
|
|
8604
|
-
if (!context) return;
|
|
8678
|
+
if (!context) return; // console.log("Component for path", path)
|
|
8679
|
+
// lookup by path
|
|
8605
8680
|
|
|
8606
8681
|
if (registry.paths[path]) {
|
|
8607
8682
|
return registry.paths[path];
|
|
8608
|
-
}
|
|
8683
|
+
} // by type
|
|
8684
|
+
|
|
8609
8685
|
|
|
8610
8686
|
if (registry.views[context['@type']]) {
|
|
8611
8687
|
return registry.views[context['@type']];
|
|
@@ -8646,6 +8722,17 @@ const getProperties = type => {
|
|
|
8646
8722
|
|
|
8647
8723
|
const getSchemas = type => {
|
|
8648
8724
|
return registry.schemas[type] || {};
|
|
8725
|
+
/*
|
|
8726
|
+
filters: [
|
|
8727
|
+
{
|
|
8728
|
+
attribute_key: string,
|
|
8729
|
+
label: string,
|
|
8730
|
+
type: 'select' | 'input'
|
|
8731
|
+
vocabulary: string | undefined
|
|
8732
|
+
values: {[key:string]:any}[]
|
|
8733
|
+
}
|
|
8734
|
+
]
|
|
8735
|
+
*/
|
|
8649
8736
|
};
|
|
8650
8737
|
|
|
8651
8738
|
const getFieldsToFilter = (type, fallback) => {
|
|
@@ -8660,6 +8747,7 @@ const defaultComponent = context => {
|
|
|
8660
8747
|
return context.is_folderish ? FolderCtx : ItemCtx;
|
|
8661
8748
|
};
|
|
8662
8749
|
function useRegistry(data) {
|
|
8750
|
+
// if data is provided we need to merge it into actual registry
|
|
8663
8751
|
const ref = React.useRef();
|
|
8664
8752
|
|
|
8665
8753
|
if (data && !ref.current) {
|
|
@@ -8681,6 +8769,22 @@ function useRegistry(data) {
|
|
|
8681
8769
|
getSchemas
|
|
8682
8770
|
};
|
|
8683
8771
|
}
|
|
8772
|
+
/*
|
|
8773
|
+
|
|
8774
|
+
const registry = {
|
|
8775
|
+
paths: {
|
|
8776
|
+
"/db/guillotina/tags/": TagsContext
|
|
8777
|
+
},
|
|
8778
|
+
forms: {
|
|
8779
|
+
Tag: AddTagForm
|
|
8780
|
+
}
|
|
8781
|
+
}
|
|
8782
|
+
|
|
8783
|
+
|
|
8784
|
+
<guillotina registry={registry} />
|
|
8785
|
+
|
|
8786
|
+
|
|
8787
|
+
*/
|
|
8684
8788
|
|
|
8685
8789
|
const initialState$4 = {
|
|
8686
8790
|
path: '',
|
|
@@ -11570,14 +11674,17 @@ function Guillotina(_ref) {
|
|
|
11570
11674
|
props = _objectWithoutPropertiesLoose(_ref, ["auth", "locale"]);
|
|
11571
11675
|
|
|
11572
11676
|
const messages = loadLocaleData(locale);
|
|
11573
|
-
const url = props.url || 'http://localhost:8080';
|
|
11677
|
+
const url = props.url || 'http://localhost:8080'; // without trailing slash
|
|
11678
|
+
|
|
11574
11679
|
const config = props.config || {};
|
|
11575
11680
|
const client = useGuillotinaClient();
|
|
11576
11681
|
const {
|
|
11577
11682
|
Permissions
|
|
11578
11683
|
} = useConfig(config);
|
|
11579
|
-
const registry = useRegistry(props.registry || {});
|
|
11580
|
-
|
|
11684
|
+
const registry = useRegistry(props.registry || {}); // Location is cooked routing solution (only uses search params)
|
|
11685
|
+
|
|
11686
|
+
const [location] = useLocation(); // if there is no path provided just go to root
|
|
11687
|
+
|
|
11581
11688
|
const searchPath = location.get('path') || '/';
|
|
11582
11689
|
|
|
11583
11690
|
if (searchPath && searchPath !== '') {
|
|
@@ -12106,6 +12213,7 @@ class Auth {
|
|
|
12106
12213
|
});
|
|
12107
12214
|
|
|
12108
12215
|
if (data.status === 401) {
|
|
12216
|
+
// invalid token
|
|
12109
12217
|
this.cleanAuth();
|
|
12110
12218
|
this.logout();
|
|
12111
12219
|
return;
|