app/assets/javascripts/components/common/namespace_select.jsx
import React, { useState, useEffect } from 'react';
import { map } from 'lodash-es';
import Select from 'react-select';
import { wikiNamespaceLabel } from '../../utils/wiki_utils';
const projects_namespaces_ids = JSON.parse(ProjectNamespaces);
const NamespaceSelect = (props) => {
const [selectedNamespaces, setSelectedNamespaces] = useState([]);
const [options, setOptions] = useState([]);
useEffect(() => {
const namespaces = props.namespaces.map((wiki_ns) => {
const wiki = wiki_ns.split('-')[0];
const namespace = wiki_ns.split('-')[2];
const label = wikiNamespaceLabel(wiki, namespace);
const value = wiki_ns;
return { label, value };
});
setSelectedNamespaces(namespaces);
}, [props.namespaces]);
useEffect(() => {
updateNamespacesFromWikis();
updateOptionsFromWikis();
}, [props.wikis]);
// Filters currently selected namespaces according to tracked wikis
// There shouldn't be any tracked namespace without corresponding tracked wiki
const updateNamespacesFromWikis = () => {
const current_namespaces = props.namespaces;
const updated_namespaces = props.wikis.map((wiki) => {
const language = wiki.language || 'www'; // for multilingual wikis, language is null
const project = wiki.project;
const domain = `${language}.${project}.org`;
return current_namespaces.filter((wiki_ns) => {
return wiki_ns.split('-')[0] === domain;
});
}).reduce((a, b) => a.concat(b));
updateNamespaces(updated_namespaces);
};
// Updates options according to tracked wikis
const updateOptionsFromWikis = () => {
const updated_options = props.wikis.map((wiki) => {
const language = wiki.language || 'www';
const project = wiki.project;
const domain = `${language}.${project}.org`;
return projects_namespaces_ids[project].map((ns) => {
const label = wikiNamespaceLabel(domain, ns);
const value = `${domain}-namespace-${ns}`;
return { label, value };
});
}).reduce((a, b) => a.concat(b));
return setOptions(updated_options);
};
const handleChange = (selectedOptions) => {
if (!selectedOptions) return updateNamespaces([]);
const tracked_namespaces = selectedOptions.map((option) => {
return option.value;
});
updateNamespaces(tracked_namespaces);
};
const updateNamespaces = (namespaces) => {
props.onChange(namespaces);
};
if (props.readOnly) {
const lastIndex = props.namespaces.length - 1;
const namespaceList = map(props.namespaces, (wiki_ns, index) => {
const comma = (index !== lastIndex) ? ', ' : '';
const wiki = wiki_ns.split('-')[0];
const namespace = wiki_ns.split('-')[2];
const label = wikiNamespaceLabel(wiki, namespace);
return <span key={wiki_ns}>{label}{comma}</span>;
});
return (
<>
{namespaceList}
</>
);
}
return (
<>
<label id="namespace-label" htmlFor="namespace_select" className="text-input-component__label inline-label">
<strong>
{I18n.t('courses.namespaces')}:
</strong>
</label>
<div className="tooltip-trigger">
<img src ="/assets/images/info.svg" alt = "tooltip default logo" />
<div className="tooltip large dark">
<p>
{I18n.t('namespace.tracked_namespaces_info')}
</p>
</div>
</div>
<Select
id = "namespace_select"
value = {selectedNamespaces}
onChange = {handleChange}
options = {options}
styles={props.styles}
isMulti = {true}
isClearable={false}
aria-labelledby="namespace-label"
/>
</>
);
};
export default NamespaceSelect;