mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fixed code smell 'Prefer using an optional chain expression instead, as it's more concise and easier to read'.
This commit is contained in:
@@ -20,7 +20,7 @@ define('app', [
|
||||
for (let key in obj) {
|
||||
let module = obj[key];
|
||||
|
||||
if (module && module.init && typeof module.init == 'function') {
|
||||
if (typeof module?.init == 'function') {
|
||||
try {
|
||||
module.init();
|
||||
}
|
||||
@@ -28,7 +28,7 @@ define('app', [
|
||||
console.warn(e.stack || e);
|
||||
}
|
||||
}
|
||||
else if (module && module.Init && typeof module.Init == 'function') {
|
||||
else if (typeof module?.Init == 'function') {
|
||||
try {
|
||||
module.Init();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ export default function MasterPasswordContent({ closeModal, onResetPassowrd, onO
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
firstEleRef.current && firstEleRef.current.focus();
|
||||
firstEleRef.current?.focus();
|
||||
}, 350);
|
||||
}, [firstEleRef.current]);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function NamedRestoreContent({closeModal, onOK, setHeight}) {
|
||||
|
||||
useEffect(()=>{
|
||||
setTimeout(()=>{
|
||||
firstEleRef.current && firstEleRef.current.focus();
|
||||
firstEleRef.current?.focus();
|
||||
}, 275);
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@ PlanContent.propTypes = {
|
||||
function PlanSVG({planData, zoomFactor, fitZoomFactor, ...props}) {
|
||||
const theme = useTheme();
|
||||
useEffect(()=>{
|
||||
fitZoomFactor && fitZoomFactor(planData.width);
|
||||
fitZoomFactor?.(planData.width);
|
||||
}, [planData.width]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -505,7 +505,7 @@ export default function Explain({plans=[]}) {
|
||||
// indicatorColor="primary"
|
||||
variant="scrollable"
|
||||
scrollButtons="auto"
|
||||
action={(ref)=>ref && ref.updateIndicator()}
|
||||
action={(ref)=>ref?.updateIndicator()}
|
||||
>
|
||||
<Tab label="Graphical" />
|
||||
<Tab label="Analysis" />
|
||||
|
||||
@@ -54,7 +54,7 @@ export function onlineHelpSearch(param, props) {
|
||||
let pooling = window.pooling;
|
||||
if(resultEl) {
|
||||
let searchResultsH2Tags = resultEl.getElementsByTagName('h2');
|
||||
let list = resultEl && resultEl.getElementsByTagName('LI');
|
||||
let list = resultEl?.getElementsByTagName('LI');
|
||||
if ((list && list.length > 0 )) {
|
||||
let res = extractSearchResult(list);
|
||||
// After getting the data, we need to call the Parent component function
|
||||
|
||||
@@ -39,7 +39,7 @@ export default class DepListener {
|
||||
if(dataPath.length > 0) {
|
||||
data = _.get(state, dataPath);
|
||||
}
|
||||
_.assign(data, listener.callback && listener.callback(data, listener.source, state, actionObj) || {});
|
||||
_.assign(data, listener.callback?.(data, listener.source, state, actionObj) || {});
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class DepListener {
|
||||
if(dataPath.length > 0) {
|
||||
data = _.get(state, dataPath);
|
||||
}
|
||||
return (listener.defCallback && listener.defCallback(data, listener.source, state, actionObj));
|
||||
return (listener.defCallback?.(data, listener.source, state, actionObj));
|
||||
}
|
||||
|
||||
/* Called when any field changed and trigger callbacks */
|
||||
|
||||
@@ -421,7 +421,7 @@ export default function FormView({
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
onTabChange && onTabChange(tabValue, Object.keys(tabs)[tabValue], sqlTabActive);
|
||||
onTabChange?.(tabValue, Object.keys(tabs)[tabValue], sqlTabActive);
|
||||
}, [tabValue]);
|
||||
|
||||
/* check whether form is kept hidden by visible prop */
|
||||
@@ -441,7 +441,7 @@ export default function FormView({
|
||||
}}
|
||||
variant="scrollable"
|
||||
scrollButtons="auto"
|
||||
action={(ref)=>ref && ref.updateIndicator()}
|
||||
action={(ref)=>ref?.updateIndicator()}
|
||||
>
|
||||
{Object.keys(finalTabs).map((tabName)=>{
|
||||
return <Tab key={tabName} label={tabName} data-test={tabName}/>;
|
||||
|
||||
@@ -28,15 +28,15 @@ function MappedFormControlBase({ type, value, id, onChange, className, visible,
|
||||
if(e?.target) {
|
||||
val = e.target.value;
|
||||
}
|
||||
onChange && onChange(val);
|
||||
onChange?.(val);
|
||||
}, []);
|
||||
|
||||
const onSqlChange = useCallback((changedValue) => {
|
||||
onChange && onChange(changedValue);
|
||||
onChange?.(changedValue);
|
||||
}, []);
|
||||
|
||||
const onTreeSelection = useCallback((selectedValues)=> {
|
||||
onChange && onChange(selectedValues);
|
||||
onChange?.(selectedValues);
|
||||
}, []);
|
||||
|
||||
if (!visible) {
|
||||
@@ -128,7 +128,7 @@ function MappedCellControlBase({ cell, value, id, optionsLoaded, onCellChange, v
|
||||
val = e.target.value;
|
||||
}
|
||||
|
||||
onCellChange && onCellChange(val);
|
||||
onCellChange?.(val);
|
||||
}, []);
|
||||
|
||||
const onRadioChange = useCallback((e) => {
|
||||
@@ -136,11 +136,11 @@ function MappedCellControlBase({ cell, value, id, optionsLoaded, onCellChange, v
|
||||
if(e?.target) {
|
||||
val = e.target.checked;
|
||||
}
|
||||
onCellChange && onCellChange(val);
|
||||
onCellChange?.(val);
|
||||
});
|
||||
|
||||
const onSqlChange = useCallback((val) => {
|
||||
onCellChange && onCellChange(val);
|
||||
onCellChange?.(val);
|
||||
}, []);
|
||||
|
||||
/* Some grid cells are based on options selected in other cells.
|
||||
@@ -148,8 +148,8 @@ function MappedCellControlBase({ cell, value, id, optionsLoaded, onCellChange, v
|
||||
*/
|
||||
const optionsLoadedRerender = useCallback((res) => {
|
||||
/* optionsLoaded is called when select options are fetched */
|
||||
optionsLoaded && optionsLoaded(res);
|
||||
reRenderRow && reRenderRow();
|
||||
optionsLoaded?.(res);
|
||||
reRenderRow?.();
|
||||
}, []);
|
||||
|
||||
if (!visible) {
|
||||
|
||||
@@ -158,7 +158,7 @@ export default class BaseUISchema {
|
||||
let res = [];
|
||||
if (state && this.isNew(state)) {
|
||||
options.forEach((option) => {
|
||||
if(option && option.label == '') {
|
||||
if(option?.label == '') {
|
||||
return;
|
||||
}
|
||||
res.push({ label: option.label, value: option.value });
|
||||
|
||||
@@ -538,7 +538,7 @@ function SchemaDialogView({
|
||||
changedData = _.assign({}, schema.origData, changedData);
|
||||
}
|
||||
|
||||
props.onDataChange && props.onDataChange(isDataChanged, changedData);
|
||||
props.onDataChange?.(isDataChanged, changedData);
|
||||
}, [sessData, formReady]);
|
||||
|
||||
useEffect(()=>{
|
||||
@@ -568,7 +568,7 @@ function SchemaDialogView({
|
||||
let unmounted = false;
|
||||
/* Docker on load focusses itself, so our focus should execute later */
|
||||
let focusTimeout = setTimeout(()=>{
|
||||
firstEleRef.current && firstEleRef.current.focus();
|
||||
firstEleRef.current?.focus();
|
||||
}, 250);
|
||||
|
||||
setLoaderText('Loading...');
|
||||
@@ -577,7 +577,7 @@ function SchemaDialogView({
|
||||
if(!getInitData && viewHelperProps.mode === 'edit') {
|
||||
throw new Error('getInitData must be passed for edit');
|
||||
}
|
||||
let initDataPromise = (getInitData && getInitData()) || Promise.resolve({});
|
||||
let initDataPromise = getInitData?.() || Promise.resolve({});
|
||||
initDataPromise.then((data)=>{
|
||||
if(unmounted) {
|
||||
return;
|
||||
@@ -628,7 +628,7 @@ function SchemaDialogView({
|
||||
|
||||
const onResetClick = ()=>{
|
||||
const resetIt = ()=>{
|
||||
firstEleRef.current && firstEleRef.current.focus();
|
||||
firstEleRef.current?.focus();
|
||||
setFormResetKey((prev)=>prev+1);
|
||||
sessDispatch({
|
||||
type: SCHEMA_STATE_ACTIONS.INIT,
|
||||
|
||||
@@ -93,7 +93,7 @@ function UtilityViewContent({panelId, schema, treeNodeInfo, actionType, formType
|
||||
}).then((res)=>{
|
||||
/* Don't warn the user before closing dialog */
|
||||
resolve(res.data);
|
||||
onSave && onSave(res.data);
|
||||
onSave?.(res.data);
|
||||
onClose();
|
||||
}).catch((err)=>{
|
||||
reject(err);
|
||||
|
||||
@@ -113,12 +113,12 @@ export default function BaseChart({type='line', id, options, data, redraw=false,
|
||||
plugins: [plugins],
|
||||
options: options,
|
||||
});
|
||||
props.onInit && props.onInit(chartObj.current);
|
||||
props.onInit?.(chartObj.current);
|
||||
};
|
||||
|
||||
const destroyChart = function() {
|
||||
chartObj.current?.resetZoom?.();
|
||||
chartObj.current && chartObj.current.destroy();
|
||||
chartObj.current?.destroy();
|
||||
};
|
||||
|
||||
useEffect(()=>{
|
||||
@@ -137,7 +137,7 @@ export default function BaseChart({type='line', id, options, data, redraw=false,
|
||||
}
|
||||
chartObj.current.options = options;
|
||||
chartObj.current.update(props.updateOptions || {});
|
||||
props.onUpdate && props.onUpdate(chartObj.current);
|
||||
props.onUpdate?.(chartObj.current);
|
||||
}
|
||||
}, [data, options]);
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ export function FindDialog({editor, show, replace, onClose, selFindVal}) {
|
||||
if(selText.length != 0) {
|
||||
setFindVal(selText);
|
||||
}
|
||||
findInputRef.current && findInputRef.current.select();
|
||||
findInputRef.current?.select();
|
||||
search();
|
||||
}
|
||||
}, [show]);
|
||||
@@ -217,7 +217,7 @@ export function FindDialog({editor, show, replace, onClose, selFindVal}) {
|
||||
};
|
||||
|
||||
const onFindNext = ()=>{
|
||||
if(searchCursor.current && searchCursor.current.find()) {
|
||||
if(searchCursor.current?.find()) {
|
||||
editor.setSelection(searchCursor.current.from(), searchCursor.current.to());
|
||||
editor.scrollIntoView({
|
||||
from: searchCursor.current.from(),
|
||||
@@ -227,7 +227,7 @@ export function FindDialog({editor, show, replace, onClose, selFindVal}) {
|
||||
};
|
||||
|
||||
const onFindPrev = ()=>{
|
||||
if(searchCursor.current && searchCursor.current.find(true)) {
|
||||
if(searchCursor.current?.find(true)) {
|
||||
editor.setSelection(searchCursor.current.from(), searchCursor.current.to());
|
||||
editor.scrollIntoView({
|
||||
from: searchCursor.current.from(),
|
||||
@@ -441,7 +441,7 @@ export default function CodeMirror({currEditor, name, value, options, events, re
|
||||
} else {
|
||||
editor.current.setValue('');
|
||||
}
|
||||
currEditor && currEditor(editor.current);
|
||||
currEditor?.(editor.current);
|
||||
if(editor.current) {
|
||||
try {
|
||||
cmWrapper.current = editor.current.getWrapperElement();
|
||||
|
||||
@@ -198,7 +198,7 @@ export function InputSQL({ value, options, onChange, className, controlProps, in
|
||||
className={clsx(classes.sql, className)}
|
||||
events={{
|
||||
change: (cm) => {
|
||||
onChange && onChange(cm.getValue());
|
||||
onChange?.(cm.getValue());
|
||||
},
|
||||
}}
|
||||
{...controlProps}
|
||||
@@ -370,7 +370,7 @@ export const InputText = forwardRef(({
|
||||
if (controlProps?.formatter) {
|
||||
changeVal = controlProps.formatter.toRaw(changeVal);
|
||||
}
|
||||
onChange && onChange(changeVal);
|
||||
onChange?.(changeVal);
|
||||
};
|
||||
|
||||
let finalValue = (_.isNull(value) || _.isUndefined(value)) ? '' : value;
|
||||
@@ -461,7 +461,7 @@ export function InputFileSelect({ controlProps, onChange, disabled, readonly, is
|
||||
btn_primary: controlProps.btnPrimary || '',
|
||||
};
|
||||
showFileManager(params, (fileName)=>{
|
||||
onChange && onChange(decodeURI(fileName));
|
||||
onChange?.(decodeURI(fileName));
|
||||
inpRef.current.focus();
|
||||
});
|
||||
};
|
||||
@@ -909,7 +909,7 @@ export const InputSelect = forwardRef(({
|
||||
.then((res) => {
|
||||
/* If component unmounted, dont update state */
|
||||
if (!umounted) {
|
||||
optionsLoaded && optionsLoaded(res, value);
|
||||
optionsLoaded?.(res, value);
|
||||
/* Auto select if any option has key as selected */
|
||||
const flatRes = flattenSelectOptions(res || []);
|
||||
let selectedVal;
|
||||
@@ -920,7 +920,7 @@ export const InputSelect = forwardRef(({
|
||||
}
|
||||
|
||||
if ((!_.isUndefined(selectedVal) && !_.isArray(selectedVal)) || (_.isArray(selectedVal) && selectedVal.length != 0)) {
|
||||
onChange && onChange(selectedVal);
|
||||
onChange?.(selectedVal);
|
||||
}
|
||||
setFinalOptions([res || [], false]);
|
||||
}
|
||||
@@ -930,7 +930,7 @@ export const InputSelect = forwardRef(({
|
||||
|
||||
|
||||
/* Apply filter if any */
|
||||
const filteredOptions = (controlProps.filter && controlProps.filter(finalOptions)) || finalOptions;
|
||||
const filteredOptions = (controlProps.filter?.(finalOptions)) || finalOptions;
|
||||
const flatFiltered = flattenSelectOptions(filteredOptions);
|
||||
let realValue = getRealValue(flatFiltered, value, controlProps.creatable, controlProps.formatter);
|
||||
if (realValue && _.isPlainObject(realValue) && _.isUndefined(realValue.value)) {
|
||||
@@ -956,9 +956,9 @@ export const InputSelect = forwardRef(({
|
||||
} else {
|
||||
selectVal = selectVal.map((option) => option.value);
|
||||
}
|
||||
onChange && onChange(selectVal);
|
||||
onChange?.(selectVal);
|
||||
} else {
|
||||
onChange && onChange(selectVal ? selectVal.value : null);
|
||||
onChange?.(selectVal ? selectVal.value : null);
|
||||
}
|
||||
}, [onChange, filteredOptions]);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export function SelectRefresh({ required, className, label, helpMessage, testcid
|
||||
const {getOptionsOnRefresh, ...selectControlProps} = controlProps;
|
||||
|
||||
const onRefreshClick = ()=>{
|
||||
getOptionsOnRefresh && getOptionsOnRefresh()
|
||||
getOptionsOnRefresh?.()
|
||||
.then((res)=>{
|
||||
setOptions(res);
|
||||
setOptionsReloadBasis((prevVal)=>!prevVal);
|
||||
|
||||
@@ -68,7 +68,7 @@ function alert(title, text, onOkClick, okLabel = gettext('OK')) {
|
||||
// bind the modal provider before calling
|
||||
this.showModal(title, (closeModal) => {
|
||||
const onOkClickClose = () => {
|
||||
onOkClick && onOkClick();
|
||||
onOkClick?.();
|
||||
closeModal();
|
||||
};
|
||||
return (
|
||||
@@ -81,11 +81,11 @@ function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes')
|
||||
// bind the modal provider before calling
|
||||
this.showModal(title, (closeModal) => {
|
||||
const onCancelClickClose = () => {
|
||||
onCancelClick && onCancelClick();
|
||||
onCancelClick?.();
|
||||
closeModal();
|
||||
};
|
||||
const onOkClickClose = () => {
|
||||
onOkClick && onOkClick();
|
||||
onOkClick?.();
|
||||
closeModal();
|
||||
};
|
||||
return (
|
||||
|
||||
@@ -45,7 +45,7 @@ function isCtrlAltBoth(event) {
|
||||
/* Returns the key of shortcut */
|
||||
function shortcut_key(shortcut) {
|
||||
let key = '';
|
||||
if(shortcut && shortcut['key'] && shortcut['key']['char']) {
|
||||
if(shortcut?.['key'] && shortcut?.['key']['char']) {
|
||||
key = shortcut['key']['char'].toUpperCase();
|
||||
}
|
||||
return key;
|
||||
|
||||
@@ -97,7 +97,7 @@ _.extend(pgBrowser.browserTreeState, {
|
||||
offRemoveFromTreeState?.();
|
||||
offUpdateTreeState?.();
|
||||
};
|
||||
|
||||
|
||||
},
|
||||
save_state: function() {
|
||||
|
||||
@@ -198,8 +198,8 @@ _.extend(pgBrowser.browserTreeState, {
|
||||
if (treeHierarchy === null || !pgBrowser.tree.hasParent(item) || !(treeHierarchy.hasOwnProperty(self.parent)))
|
||||
return;
|
||||
|
||||
let topParent = treeHierarchy && treeHierarchy[self.parent]['_id'],
|
||||
origParent = treeHierarchy && treeHierarchy[self.orig_parent]['id'];
|
||||
let topParent = treeHierarchy?.[self.parent]['_id'],
|
||||
origParent = treeHierarchy?.[self.orig_parent]['id'];
|
||||
|
||||
this.update_database_status(item);
|
||||
|
||||
@@ -308,7 +308,7 @@ _.extend(pgBrowser.browserTreeState, {
|
||||
|
||||
if (treeHierarchy.hasOwnProperty('database')) {
|
||||
let databaseItem = treeHierarchy['database']['id'],
|
||||
topParent = treeHierarchy && treeHierarchy[this.parent]['_id'];
|
||||
topParent = treeHierarchy?.[this.parent]['_id'];
|
||||
|
||||
if (topParent in this.current_state && 'selected' in this.current_state[topParent]) {
|
||||
if (treeHierarchy['database'].connected) {
|
||||
@@ -333,7 +333,7 @@ _.extend(pgBrowser.browserTreeState, {
|
||||
if (!(this.parent in treeHierarchy))
|
||||
return;
|
||||
|
||||
let topParent = treeHierarchy && treeHierarchy[this.parent]['_id'],
|
||||
let topParent = treeHierarchy?.[this.parent]['_id'],
|
||||
selectedItem = pgBrowser.tree.itemData(pgBrowser.tree.selected()),
|
||||
databaseItem = undefined;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ function manageTreeEvents(event, eventName, item) {
|
||||
let obj = pgAdmin.Browser;
|
||||
|
||||
// Events for preferences tree.
|
||||
if (node_metadata.parent && node_metadata.parent.includes('/preferences') && obj.ptree.tree.type == 'preferences') {
|
||||
if (node_metadata.parent?.includes('/preferences') && obj.ptree.tree.type == 'preferences') {
|
||||
try {
|
||||
obj.Events.trigger(
|
||||
'preferences:tree:' + eventName, event, item, d
|
||||
@@ -191,7 +191,7 @@ export class Tree {
|
||||
}
|
||||
|
||||
async addIcon(item, icon) {
|
||||
if (item !== undefined && item.getMetadata('data') !== undefined) {
|
||||
if (item?.getMetadata('data') !== undefined) {
|
||||
item.getMetadata('data').icon = icon.icon;
|
||||
}
|
||||
await this.tree.addIcon(item, icon);
|
||||
@@ -231,7 +231,7 @@ export class Tree {
|
||||
}
|
||||
|
||||
wasLoad(item) {
|
||||
if (item && item.type === FileType.Directory) {
|
||||
if (item?.type === FileType.Directory) {
|
||||
return item.isExpanded && item.children != null && item.children.length > 0;
|
||||
}
|
||||
return true;
|
||||
@@ -247,7 +247,7 @@ export class Tree {
|
||||
return model.root.children[0];
|
||||
}
|
||||
|
||||
if (item !== undefined && item !== null && item.branchSize > 0) {
|
||||
if (item?.branchSize > 0) {
|
||||
return item.children[0];
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ export class Tree {
|
||||
}
|
||||
|
||||
hasParent(item) {
|
||||
return item && item.parent ? true : false;
|
||||
return item?.parent ? true : false;
|
||||
}
|
||||
|
||||
isOpen(item) {
|
||||
@@ -319,11 +319,11 @@ export class Tree {
|
||||
}
|
||||
|
||||
itemData(item) {
|
||||
return (item !== undefined && item !== null && item.getMetadata('data') !== undefined) ? item._metadata.data : [];
|
||||
return (item?.getMetadata('data') !== undefined) ? item?._metadata.data : [];
|
||||
}
|
||||
|
||||
getData(item) {
|
||||
return (item !== undefined && item.getMetadata('data') !== undefined) ? item._metadata.data : [];
|
||||
return (item?.getMetadata('data') !== undefined) ? item?._metadata.data : [];
|
||||
}
|
||||
|
||||
isRootNode(item) {
|
||||
@@ -411,7 +411,7 @@ export class Tree {
|
||||
|
||||
findNodeByDomElement(domElement) {
|
||||
const path = domElement.path;
|
||||
if (!path || !path[0]) {
|
||||
if (!path?.[0]) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ export class Tree {
|
||||
|
||||
createOrUpdateNode(id, data, parent, domNode) {
|
||||
let oldNodePath = id;
|
||||
if (parent !== null && parent !== undefined && parent.path !== undefined && parent.path != '/browser') {
|
||||
if (parent?.path != '/browser') {
|
||||
oldNodePath = parent.path + '/' + id;
|
||||
}
|
||||
const oldNode = this.findNode(oldNodePath);
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
let getWindowOpener = (opener) => {
|
||||
return opener.opener && opener.opener.pgAdmin ? getWindowOpener(opener.opener) : opener;
|
||||
return opener.opener?.pgAdmin ? getWindowOpener(opener.opener) : opener;
|
||||
};
|
||||
|
||||
let pgWindow = function() {
|
||||
let localPgWindow = null;
|
||||
try {
|
||||
if(window.opener && window.opener.pgAdmin) {
|
||||
if(window.opener?.pgAdmin) {
|
||||
/* Windows can be opened at multiple levels */
|
||||
localPgWindow = getWindowOpener(window.opener);
|
||||
} else if(window.parent && window.parent.pgAdmin){
|
||||
} else if(window.parent?.pgAdmin){
|
||||
localPgWindow = window.parent;
|
||||
} else if(window.top && window.top.pgAdmin){
|
||||
} else if(window.top?.pgAdmin){
|
||||
localPgWindow = window.top;
|
||||
} else {
|
||||
localPgWindow = window;
|
||||
|
||||
2
web/pgadmin/static/vendor/require/require.js
vendored
2
web/pgadmin/static/vendor/require/require.js
vendored
@@ -1237,7 +1237,7 @@ var requirejs, require, define;
|
||||
|
||||
return {
|
||||
node: node,
|
||||
id: node && node.getAttribute('data-requiremodule')
|
||||
id: node?.getAttribute('data-requiremodule')
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user