diff --git a/src/actions/email-actions.js b/src/actions/email-actions.js index 2e0799df0..63f6ff57c 100644 --- a/src/actions/email-actions.js +++ b/src/actions/email-actions.js @@ -251,7 +251,7 @@ const normalizeEntity = (entity) => { return normalizedEntity; }; -export const queryTemplates = debounce(async (input, callback) => { +export const queryTemplates = debounce(async (input, callback, onError) => { const accessToken = await getAccessTokenSafely(); const endpoint = URI(`${window.EMAIL_API_BASE_URL}/api/v1/mail-templates`); @@ -274,7 +274,10 @@ export const queryTemplates = debounce(async (input, callback) => { callback(options); }) - .catch(fetchErrorHandler); + .catch((err) => { + fetchErrorHandler(err); + if (onError) onError(err); + }); }, DEBOUNCE_WAIT); /** ********************************************************************************************************* */ diff --git a/src/i18n/en.json b/src/i18n/en.json index 58eb3a2c0..9406755e9 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -3265,6 +3265,7 @@ } }, "emails": { + "emails": "Emails", "email_templates": "Email Templates", "sent": "Sent", "templates": "Templates", @@ -3319,6 +3320,9 @@ "email_logs": "Email Logs", "email_list": "Email List", "apply_filters": "Apply Filters", + "enabled_filters": "Enabled Filters", + "all": "All", + "not_sent": "Not Sent", "email_templates": "Email Templates", "subject": "Subject", "from_email": "From Email", @@ -3328,7 +3332,6 @@ "payload": "Payload", "select_fields": "Show Columns", "placeholders": { - "select_fields": "Select data to display", "template": "Filter by Template", "sent_date_from": "Filter Sent Date from", "sent_date_to": "Filter Sent Date to" diff --git a/src/pages/emails/email-log-list-page.js b/src/pages/emails/email-log-list-page.js index 417c16571..7fe83ecdc 100644 --- a/src/pages/emails/email-log-list-page.js +++ b/src/pages/emails/email-log-list-page.js @@ -11,40 +11,54 @@ * limitations under the License. * */ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { connect } from "react-redux"; import T from "i18n-react/dist/i18n-react"; -import { Pagination } from "react-bootstrap"; -import FreeTextSearch from "openstack-uicore-foundation/lib/components/free-text-search" -import Table from "openstack-uicore-foundation/lib/components/table" -import Dropdown from "openstack-uicore-foundation/lib/components/inputs/dropdown" -import DateTimePicker from "openstack-uicore-foundation/lib/components/inputs/datetimepicker"; +import { + Autocomplete, + Box, + Button, + CircularProgress, + FormControl, + Grid2, + InputLabel, + MenuItem, + OutlinedInput, + Select, + TextField, + ToggleButton, + ToggleButtonGroup +} from "@mui/material"; +import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; +import MuiTable from "openstack-uicore-foundation/lib/components/mui/table"; +import SearchInput from "openstack-uicore-foundation/lib/components/mui/search-input"; import { epochToMomentTimeZone } from "openstack-uicore-foundation/lib/utils/methods"; -import { SegmentedControl } from "segmented-control"; -import { getSentEmails } from "../../actions/email-actions"; -import "../../styles/email-logs-page.less"; -import EmailTemplateInput from "../../components/inputs/email-template-input"; +import { getSentEmails, queryTemplates } from "../../actions/email-actions"; import { DATE_FILTER_ARRAY_SIZE, DEFAULT_CURRENT_PAGE } from "../../utils/constants"; -const SentEmailListPage = function ({ +const SentEmailListPage = ({ emails, - lastPage, currentPage, term, order, orderDir, totalEmails, - match, perPage, filters, - getSentEmails, - ...props -}) { + getSentEmails +}) => { useEffect(() => { - getSentEmails(term, currentPage, perPage, order, orderDir, filters); + getSentEmails( + term, + DEFAULT_CURRENT_PAGE, + perPage, + order, + orderDir, + filters + ); }, []); const defaultFilters = { @@ -65,15 +79,52 @@ const SentEmailListPage = function ({ ...filters }); const [selectedColumns, setSelectedColumns] = useState([]); + const [templateOptions, setTemplateOptions] = useState([]); + const [templateLoading, setTemplateLoading] = useState(false); + const templateRequestSeqRef = useRef(0); + + const fetchTemplateOptions = (input) => { + const seq = ++templateRequestSeqRef.current; + setTemplateLoading(true); + queryTemplates( + input, + (results) => { + if (seq !== templateRequestSeqRef.current) return; + setTemplateOptions( + results.map((t) => ({ value: t.identifier, label: t.identifier })) + ); + setTemplateLoading(false); + }, + () => { + if (seq !== templateRequestSeqRef.current) return; + setTemplateLoading(false); + } + ); + }; + + useEffect(() => { + fetchTemplateOptions(""); + }, []); const handlePageChange = (newPage) => { getSentEmails(term, newPage, perPage, order, orderDir, emailFilters); }; - const handleSort = (index, key, dir, func) => { + const handleSort = (index, key, dir) => { getSentEmails(term, currentPage, perPage, key, dir, emailFilters); }; + const handlePerPageChange = (newPerPage) => { + getSentEmails( + term, + DEFAULT_CURRENT_PAGE, + newPerPage, + order, + orderDir, + emailFilters + ); + }; + const handleSearch = (newTerm) => { getSentEmails( newTerm, @@ -113,37 +164,19 @@ const SentEmailListPage = function ({ } }; - const handleChangeDateFilter = (ev, lastDate) => { - const { value, id } = ev.target; - const newDateFilter = emailFilters[id]; + const handleChangeDateFilter = (value, lastDate) => { + const newDateFilter = emailFilters.sent_date_filter; setEmailFilters({ ...emailFilters, - [id]: lastDate - ? [newDateFilter[0], value.unix()] - : [value.unix(), newDateFilter[1]] + sent_date_filter: lastDate + ? [newDateFilter[0], value ? value.unix() : null] + : [value ? value.unix() : null, newDateFilter[1]] }); }; const handleEmailFilterChange = (ev) => { - const { type, id } = ev.target; - let { value } = ev.target; - if (type === "operatorinput") { - value = Array.isArray(value) - ? value - : `${ev.target.operator}${ev.target.value}`; - if (id === "duration_filter") { - value = Array.isArray(value) - ? value - : `${ev.target.operator}${ev.target.value}`; - } - } - if (type === "mediatypeinput") { - value = { - operator: ev.target.operator, - value: ev.target.value - }; - } + const { id, value } = ev.target; setEmailFilters({ ...emailFilters, [id]: value }); }; @@ -170,11 +203,11 @@ const SentEmailListPage = function ({ }; const fieldNames = [ - { columnKey: "last_error", value: "last_error" }, + { columnKey: "last_error", header: "last_error" }, { columnKey: "payload", - value: "payload", - render: (row, data) =>