✨ Filterting by query and org unit

This commit is contained in:
nikolark committed 2020-01-05 16:38:48 +01:00
1 parent 865ae17785
commit a94bbed03b
7 files changed
+99 -66

No files matched your search

+2 -4
View File
@@ -4,9 +4,8 @@ import { RestLink } from 'apollo-link-rest';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { OrgUnitList, MainArea } from './components';
import { getCookie } from './utils';
import MailAdmin from './components/MailAdmin';
const restLink = new RestLink({
uri: '/api/',
@@ -25,8 +24,7 @@ const App = () => (
<ApolloProvider client={client}>
<div className="container" style={{ marginTop: '2rem' }}>
<div className="row">
<OrgUnitList />
<MainArea />
<MailAdmin />
</div>
</div>
</ApolloProvider>
+1 -1
View File
@@ -23,7 +23,7 @@
}
}
a {
padding: 0.5rem 0.8rem;
padding: 0.1rem 0.4rem;
display: block;
@@ -7,10 +7,11 @@ import { DELETE_ALIASES_MUTATION } from '../mutations';
import { notify } from '../utils';
import { GET_ALIASES } from '../queries';
const AliasRow = ({ id, destination, updateDeletionList }) => {
const AliasRow = ({ id, destination, query, updateDeletionList }) => {
const [checked, setChecked] = useState(false);
const queryMatch = query && destination.includes(query);
return (
<tr className={ctx({ 'table-danger': checked })}>
<tr className={ctx({ 'table-danger': checked, 'table-success': queryMatch })}>
<td>{destination}</td>
<td className="del-cell">
<div className="custom-control custom-checkbox custom-control-inline">
@@ -49,7 +50,7 @@ const ActionRow = ({ onAddEmailClick, deleteVisible, onDelete }) => {
);
};
const AliasList = ({ list, aliases, domain }) => {
const AliasList = ({ list, aliases, domain, query }) => {
const [textareaVisible, setTextareaVisible] = useState(false);
const [deletionList, setDeletionList] = useState([]);
const [deleteAliases] = useMutation(DELETE_ALIASES_MUTATION);
@@ -106,6 +107,7 @@ const AliasList = ({ list, aliases, domain }) => {
setDeletionList(deletionList.filter(({ id }) => id !== aliasId)); // remove
}
}}
query={query}
/>
))}
<ActionRow
@@ -13,6 +13,8 @@ const AliasListCreate = ({ domain, lists, orgUnits }) => {
const listName = `${selectedPrefix}-${name}@${domain.name}`;
const shouldCreate = Boolean(Object.entries(lists).filter(([list]) => list === listName).length);
const flattenedPrefixes = [].concat(...orgUnits.map((ou) => ou.prefixes.map((prefix) => prefix))).sort();
return (
<div className="new-list-container">
<button
@@ -44,21 +46,19 @@ const AliasListCreate = ({ domain, lists, orgUnits }) => {
{selectedPrefix}- <span className="caret" />
</button>
<div className="dropdown-menu prefix-select">
{orgUnits.map((ou) =>
ou.prefixes.map((prefix) => (
<a
key={`${ou.id}-${prefix}`}
className="dropdown-item"
href="#"
onClick={(e) => {
e.preventDefault();
setSelectedPrefix(prefix);
}}
>
{prefix}-
</a>
))
)}
{flattenedPrefixes.map((prefix) => (
<a
key={prefix}
className="dropdown-item"
href="#"
onClick={(e) => {
e.preventDefault();
setSelectedPrefix(prefix);
}}
>
{prefix}-
</a>
))}
</div>
</div>
<input
@@ -0,0 +1,36 @@
import React, { useState } from 'react';
import { useQuery } from '@apollo/react-hooks';
import { MainArea, OrgUnitList } from './index';
import { GET_ORG_UNITS } from '../queries';
const MailAdmin = () => {
const [query, setQuery] = useState(new URLSearchParams(window.location.search).get('q') || '');
const [selectedOrgUnit, setOrgUnit] = useState(
parseInt(new URLSearchParams(window.location.search).get('orgunit'), 10) || null
);
const { data, loading, error } = useQuery(GET_ORG_UNITS);
if (loading || error) {
return null;
}
// Format a prefix regex for each org unit
const orgUnits = data.orgUnits.map((ou) => {
const prefixes = ou.prefixes.map((prefix) => {
return `^${prefix}-|^${prefix}@`;
});
return { prefixesRegex: prefixes.join('|'), ...ou };
});
return (
<>
<OrgUnitList
query={query}
setQuery={setQuery}
selectedOrgUnit={selectedOrgUnit}
setOrgUnit={setOrgUnit}
orgUnits={orgUnits}
/>
<MainArea query={query} selectedOrgUnit={selectedOrgUnit} orgUnits={orgUnits} />
</>
);
};
export default MailAdmin;
@@ -2,41 +2,50 @@ import React from 'react';
import { groupBy, sortBy } from 'lodash';
import { useQuery } from '@apollo/react-hooks';
import { GET_ALIASES, GET_DOMAINS, GET_ORG_UNITS } from '../queries';
import { GET_ALIASES, GET_DOMAINS } from '../queries';
import AliasList from './AliasList';
import AliasListCreate from './AliasListCreate';
const MainArea = ({ filterQuery }) => {
// TODO: Filter aliases by filterQuery
const MainArea = ({ query, selectedOrgUnit, orgUnits }) => {
const { data, loading, error } = useQuery(GET_ALIASES);
const { data: ouData, loading: ouLoading, error: ouError } = useQuery(GET_ORG_UNITS);
const { data: domainData, loading: domainLoading, error: domainError } = useQuery(GET_DOMAINS);
if (loading || ouLoading || domainLoading) {
if (loading || domainLoading) {
return (
<div className="forwards-container">
<span className="fas fa-sync spin" aria-hidden="true" /> Laster...
</div>
);
}
if (error || ouError || domainError) {
if (error || domainError) {
return null;
}
const { orgUnits } = ouData;
const domain = domainData.domains[0];
const lists = groupBy(
sortBy(data.aliases, (alias) => alias.source),
(alias) => alias.source
);
const listPrefixes = selectedOrgUnit && orgUnits.find(({ id }) => id === selectedOrgUnit).prefixesRegex;
const listRegex = listPrefixes && new RegExp(listPrefixes);
return (
<div className="col-sm-8">
{/* <div className="orgunit-select-container"></div> */}
<AliasListCreate lists={lists} orgUnits={orgUnits} domain={domain} />
<div className="forwards-container">
{Object.entries(lists).map(([list, aliases]) => (
<AliasList key={list} list={list} aliases={aliases} domain={domain} />
))}
{Object.entries(lists).map(([list, aliases]) => {
// When searching only render lists with query matches
const queryMatchInList = aliases.some((alias) => alias.destination.includes(query));
if (query && !queryMatchInList) {
return null;
}
// Only render lists which matches the org units prefixes
if (listRegex && !listRegex.test(list)) {
return null; // FIXME: use styles to show/hide ?
}
return <AliasList key={list} list={list} aliases={aliases} domain={domain} query={query} />;
})}
</div>
</div>
);
@@ -1,9 +1,7 @@
import React, { useState, useCallback } from 'react';
import { useQuery } from '@apollo/react-hooks';
import React, { useCallback } from 'react';
import ctx from 'classnames';
import { setQueryString } from '../utils';
import { GET_ORG_UNITS } from '../queries';
const Search = ({ query, setQuery }) => {
return (
@@ -25,11 +23,7 @@ const OrgUnit = ({ id, name, selected, onClick }) => (
</li>
);
const OrgUnitList = () => {
const [query, setQuery] = useState(new URLSearchParams(window.location.search).get('q') || '');
const [selected, setSelected] = useState(null);
const { data, loading, error } = useQuery(GET_ORG_UNITS);
const OrgUnitList = ({ query, setQuery, orgUnits, selectedOrgUnit, setOrgUnit }) => {
const setSearchQuery = useCallback(
(e) => {
e.preventDefault();
@@ -40,42 +34,36 @@ const OrgUnitList = () => {
[setQuery]
);
if (loading || error) {
return null;
}
const orgUnits = data.orgUnits.map((ou) => {
const prefixes = ou.prefixes.map((prefix) => {
return `^${prefix}-|^${prefix}@`;
});
return { prefixesRegex: prefixes.join('|'), ...ou };
});
const onClearOrgUnit = useCallback(
(e) => {
e.preventDefault();
setOrgUnit(null);
setQueryString();
setQuery('');
},
[setOrgUnit, setQuery]
);
return (
<div className="col-sm-4 sidebar">
<Search query={query} setQuery={setSearchQuery} />
<h5>Foreninger/Utvalg</h5>
<ul className="nav nav-sidebar orgunit-list">
<li className={ctx({ active: selected === null })}>
<a
href="/lists/"
onClick={(e) => {
e.preventDefault();
setSelected(null);
setQueryString();
}}
>
<li className={ctx({ active: selectedOrgUnit === null })}>
<a href="#" onClick={onClearOrgUnit}>
Alle
</a>
</li>
{orgUnits.map((orgUnit) => (
{orgUnits.map((ou) => (
<OrgUnit
key={orgUnit.id}
{...orgUnit}
selected={selected === orgUnit.id}
key={ou.id}
{...ou}
selected={selectedOrgUnit === ou.id}
onClick={(e) => {
e.preventDefault();
setSelected(orgUnit.id);
setQueryString({ orgunit: orgUnit.id });
setOrgUnit(ou.id);
setQueryString({ orgunit: ou.id });
setQuery('');
}}
/>
))}