✨ Filterting by query and org unit
This commit is contained in:
1 parent
865ae17785
commit
a94bbed03b
7 files changed
+99
-66
No files matched your search
@@ -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>
|
||||
|
||||
@@ -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('');
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
Reference in new issue
Block a user