at the end of the day, it was inevitable

This commit is contained in:
Mo Elzubeir
2022-12-09 08:36:26 -06:00
commit 1218570914
1768 changed files with 887087 additions and 0 deletions
@@ -0,0 +1,61 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import InputField from './InputField'
import { Card, CardBody, CardTitle, Form, FormGroup, Input, Label } from 'reactstrap'
export class BasicGroupInfo extends React.Component {
static propTypes = {
t: PropTypes.func.isRequired,
item: PropTypes.object.isRequired,
formActions: PropTypes.object.isRequired
};
onChangeFor = (field) => (event) => {
const { formActions } = this.props
formActions.changeField(field, event.target.value)
};
render () {
const { t, item } = this.props
return (
<Card>
<CardBody>
<CardTitle>{t('manageRecipientsTab.form.group.basicInfo')}</CardTitle>
<Form>
<InputField
formType="group"
field="name"
value={item.name}
onChangeFor={this.onChangeFor}
/>
<FormGroup>
<Label>
{t('manageRecipientsTab.form.group.description')}
</Label>
<Input
type="textarea"
rows="5"
onChange={this.onChangeFor('description')}
value={item.description}
/>
</FormGroup>
</Form>
<hr />
{!!item.recipients && (
<p>
{t('manageRecipientsTab.form.group.recipientsNumber')}:{' '}
{item.recipients.length}
</p>
)}
</CardBody>
</Card>
)
}
}
export default translate(['tabsContent'], { wait: true })(BasicGroupInfo)
@@ -0,0 +1,54 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import InputField from './InputField'
import { Card, CardBody, CardTitle, Form } from 'reactstrap'
export class BasicRecipientInfo extends React.Component {
static propTypes = {
t: PropTypes.func.isRequired,
item: PropTypes.object.isRequired,
formActions: PropTypes.object.isRequired
}
onChangeFor = (field) => (event) => {
const { formActions } = this.props
formActions.changeField(field, event.target.value)
}
render() {
const { item, t } = this.props
return (
<Card>
<CardBody>
<CardTitle>{t('manageRecipientsTab.form.recipient.basicInfo')}</CardTitle>
<Form>
<InputField
formType="recipient"
field="firstName"
value={item.firstName}
onChangeFor={this.onChangeFor}
/>
<InputField
formType="recipient"
field="lastName"
value={item.lastName}
onChangeFor={this.onChangeFor}
/>
<InputField
formType="recipient"
field="email"
value={item.email}
onChangeFor={this.onChangeFor}
/>
</Form>
</CardBody>
</Card>
)
}
}
export default translate(['tabsContent'], { wait: true })(BasicRecipientInfo)
@@ -0,0 +1,27 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
export class BreadCrumbs extends React.Component {
static propTypes = {
t: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
onBack: PropTypes.func.isRequired
};
render () {
const { t, title, onBack } = this.props
return (
<div>
<a href="#" onClick={onBack}>
{t('tableSwitcher.recipients')}
</a>
<span> &gt; {title}</span>
</div>
)
}
}
export default translate(['tabsContent'], { wait: true })(BreadCrumbs)
@@ -0,0 +1,119 @@
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import Toggler from '../../../../../common/Table/Toggler'
import { Button, Card, CardBody, CardTitle, Label } from 'reactstrap'
import { convertUTCtoLocal } from '../../../../../../common/helper'
export class FormTopBar extends React.Component {
static propTypes = {
t: PropTypes.func.isRequired,
formType: PropTypes.string.isRequired,
receiver: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired
}
togglerAction = () => {
const { actions, formType } = this.props
actions.shareForms[formType].toggleActive()
}
onBack = () => {
this.props.actions.switchShareSubScreen('recipients', 'tables')
}
onDelete = () => {
const { formType, actions } = this.props
actions.shareForms[formType].confirmDelete()
}
onSave = () => {
const { actions, formType } = this.props
actions.shareForms[formType].saveReceiver()
}
render() {
const { t, formType, receiver } = this.props
const hasItem = !!receiver.id
const trPath = 'manageRecipientsTab.form'
let title = t(`${trPath}.${formType}.unsaved`)
if (hasItem) {
title =
formType === 'group'
? receiver.name
: `${receiver.firstName} ${receiver.lastName}`
}
return (
<Fragment>
<Button
className="btn-wide mb-3"
size="sm"
color="info"
onClick={this.onBack}
>
<i className="lnr lnr-chevron-left"> </i>
</Button>
<Card className="main-card mb-3">
<CardBody>
<CardTitle>{title}</CardTitle>
<div className="d-flex justify-content-between flex-wrap align-items-center">
<div>
<Label className="mr-2">
{t(`${trPath}.${formType}.nameStatus`)}
</Label>
<Toggler
id={receiver.id}
turnOnAction={this.togglerAction}
turnOffAction={this.togglerAction}
state={receiver.active}
enabledText="active"
disabledText="paused"
/>
</div>
<div>
{hasItem && (
<Button
color="danger"
className="btn-icon mr-2"
onClick={this.onDelete}
>
<i className="lnr lnr-trash btn-icon-wrapper"></i>
{t(`${trPath}.${formType}.deleteButton`)}
</Button>
)}
<Button
color="secondary"
className="btn-icon mr-2"
onClick={this.onBack}
>
<i className="lnr lnr-cross btn-icon-wrapper"></i>
{t(`${trPath}.cancel`)}
</Button>
<Button
color="success"
className="btn-icon mr-2"
onClick={this.onSave}
>
<i className="lnr lnr-checkmark-circle btn-icon-wrapper" />
{t(`${trPath}.save`)}
</Button>
</div>
</div>
{hasItem && receiver.creationDate && (
<p className="mt-1">
{t(`${trPath}.${formType}.creationDate`)}:
{convertUTCtoLocal(receiver.creationDate, 'DD MMM YYYY HH:mm')}
</p>
)}
</CardBody>
</Card>
</Fragment>
)
}
}
export default translate(['tabsContent'], { wait: true })(FormTopBar)
@@ -0,0 +1,29 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import { FormGroup, Input, Label } from 'reactstrap'
export class InputField extends React.Component {
static propTypes = {
t: PropTypes.func.isRequired,
formType: PropTypes.string.isRequired,
field: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onChangeFor: PropTypes.func.isRequired
};
render () {
const { t, formType, field, value, onChangeFor } = this.props
const trPath = `manageRecipientsTab.form.${formType}`
return (
<FormGroup>
<Label>{t(`${trPath}.${field}`)}</Label>
<Input type="text" onChange={onChangeFor(field)} value={value} />
</FormGroup>
)
}
}
export default translate(['tabsContent'], { wait: true })(InputField)
@@ -0,0 +1,138 @@
import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import FormTopBar from './FormTopBar'
import BasicRecipientInfo from './BasicRecipientInfo'
import BasicGroupInfo from './BasicGroupInfo'
import TablesTabs from './TablesTabs'
import EmailHistoryTable from './tables/EmailHistoryTable'
import DeletePopup from '../../common/DeletePopup'
import {
RECIPIENT_FORM_TABLES,
GROUP_FORM_TABLES,
RECEIVER_SUBSCREENS
} from '../../../../../../redux/modules/appState/share/tabs'
import ReceiverSubscriptionsTable from './tables/ReceiverSubscriptionsTable'
import ReceiverGroupsTable from './tables/ReceiverGroupsTable'
import ReceiverRecipientsTable from './tables/ReceiverRecipientsTable'
import { Card, CardBody, CardHeader, Col, Nav, Row } from 'reactstrap'
export class RecipientForm extends React.Component {
static propTypes = {
formType: PropTypes.string.isRequired,
shareState: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired
}
chooseTableTab = (tab) => {
const { actions, formType } = this.props
actions.shareForms[formType].chooseTableTab(tab)
}
render() {
const { formType, shareState, actions } = this.props
const formState = shareState.forms[formType] // receiver
const formActions = actions.shareForms[formType]
let allTabs = formState.tabs.all
if (!formState.id) {
allTabs = allTabs.filter(
(tab) => tab !== RECIPIENT_FORM_TABLES.EMAIL_HISTORY
)
}
const activeTab = formState.tabs.active
const tableState = shareState.tables.receiverForm[activeTab]
const tableActions = actions.shareTables.receiverForm[activeTab]
const deleteText =
formType === RECEIVER_SUBSCREENS.GROUP_FORM ? 'group' : 'recipient'
return (
<Fragment>
<FormTopBar
formType={formType}
receiver={formState}
actions={actions}
/>
<Row>
<Col lg="4">
{formType === RECEIVER_SUBSCREENS.RECIPIENT_FORM && (
<BasicRecipientInfo item={formState} formActions={formActions} />
)}
{formType === RECEIVER_SUBSCREENS.GROUP_FORM && (
<BasicGroupInfo item={formState} formActions={formActions} />
)}
</Col>
<Col lg="8">
<Card className="mb-3">
<CardHeader>
<Nav justified>
<TablesTabs
tabs={allTabs}
activeTab={activeTab}
chooseTableTab={this.chooseTableTab}
/>
</Nav>
</CardHeader>
<CardBody>
{activeTab === RECIPIENT_FORM_TABLES.SUBSCRIPTIONS && (
<ReceiverSubscriptionsTable
tableState={tableState}
actions={actions}
tableActions={tableActions}
receiver={formState}
formActions={formActions}
/>
)}
{activeTab === RECIPIENT_FORM_TABLES.GROUPS && (
<ReceiverGroupsTable
tableState={tableState}
actions={actions}
tableActions={tableActions}
receiver={formState}
formActions={formActions}
/>
)}
{activeTab === RECIPIENT_FORM_TABLES.EMAIL_HISTORY && (
<EmailHistoryTable
type={activeTab}
tableState={tableState}
actions={actions}
tableActions={tableActions}
receiver={formState}
/>
)}
{activeTab === GROUP_FORM_TABLES.RECIPIENTS && (
<ReceiverRecipientsTable
tableState={tableState}
actions={actions}
tableActions={tableActions}
receiver={formState}
formActions={formActions}
/>
)}
</CardBody>
</Card>
</Col>
</Row>
{formState.isDeletePopupVisible && (
<DeletePopup
actions={formActions}
idsToDelete={[formState.id]}
deleteSingleText={deleteText}
/>
)}
</Fragment>
)
}
}
export default translate(['tabsContent'], { wait: true })(RecipientForm)
@@ -0,0 +1,35 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import { NavItem, NavLink } from 'reactstrap'
export class TablesTabs extends React.Component {
static propTypes = {
t: PropTypes.func.isRequired,
tabs: PropTypes.array.isRequired,
activeTab: PropTypes.string.isRequired,
chooseTableTab: PropTypes.func.isRequired
}
chooseTableTab = (tab) => () => {
this.props.chooseTableTab(tab)
}
render() {
const { t, tabs, activeTab } = this.props
return tabs.map((tab, i) => (
<NavItem key={tab}>
<NavLink
key={`table-tab-${i}`}
active={tab === activeTab}
onClick={this.chooseTableTab(tab)}
>
{t(`manageRecipientsTab.tables.${tab}`)}
</NavLink>
</NavItem>
))
}
}
export default translate(['tabsContent'], { wait: true })(TablesTabs)
@@ -0,0 +1,45 @@
import React from 'react'
import PropTypes from 'prop-types'
import {translate} from 'react-i18next'
import ReceiverFormTable from './ReceiverFormTable'
import SortableTh from '../../../../../../common/Table/SortableTh'
import { convertUTCtoLocal } from '../../../../../../../common/helper'
export class EmailHistoryTable extends ReceiverFormTable {
static propTypes = {
t: PropTypes.func.isRequired,
receiver: PropTypes.object.isRequired,
tableState: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
tableActions: PropTypes.object.isRequired
};
defineColumns () {
const {t} = this.props
return {
...super.defineColumns(),
'ScheduledTimes': {
sortable: false,
Header: t('notificationsTab.ScheduledTimes'),
accessor: item => this.scheduleFormat(item.schedule),
width: 170
},
'sentTime': {
Header: <SortableTh title='notificationsTab.sentTime' />,
accessor: item => convertUTCtoLocal(item.sentTime, 'DD MMM YYYY HH:mm'),
width: 170
}
}
}
getColumns () {
return ['name', 'type', 'ScheduledTimes', 'sentTime']
}
noCard () {
return true
}
}
export default translate(['tabsContent'], { wait: true })(EmailHistoryTable)
@@ -0,0 +1,82 @@
import React from 'react'
import PropTypes from 'prop-types'
import { translate } from 'react-i18next'
import TableFilter from '../../TableFilter'
import { Nav, NavItem, NavLink } from 'reactstrap'
class FormTableTopBar extends React.Component {
static propTypes = {
tableActions: PropTypes.object.isRequired,
statusFilter: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
yesText: PropTypes.string.isRequired,
noText: PropTypes.string.isRequired,
allText: PropTypes.string.isRequired,
receiver: PropTypes.object.isRequired,
t: PropTypes.func.isRequired
}
onFilterRequest = (filter) => {
const { tableActions, receiver } = this.props
tableActions.loadTable({ filter }, receiver)
}
onStatusFilter = (statusFilter) => {
return () => {
const { tableActions, receiver } = this.props
tableActions.loadTable({ statusFilter }, receiver)
}
}
render() {
const {
type,
t,
yesText,
noText,
allText,
statusFilter,
receiver
} = this.props
return (
<div>
{receiver.id && (
<Nav pills justified>
<NavItem>
<NavLink
className="d-block"
active={statusFilter === 'all'}
onClick={this.onStatusFilter('all')}
>
{t('manageRecipientsTab.' + allText)}
</NavLink>
</NavItem>
<NavItem>
<NavLink
className="d-block"
active={statusFilter === 'yes'}
onClick={this.onStatusFilter('yes')}
>
{t('manageRecipientsTab.' + yesText)}
</NavLink>
</NavItem>
<NavItem>
<NavLink
className="d-block"
active={statusFilter === 'no'}
onClick={this.onStatusFilter('no')}
>
{t('manageRecipientsTab.' + noText)}
</NavLink>
</NavItem>
</Nav>
)}
<TableFilter type={type} onFilterRequest={this.onFilterRequest} />
</div>
)
}
}
export default translate(['tabsContent'], { wait: true })(FormTableTopBar)
@@ -0,0 +1,45 @@
import React from 'react'
import PropTypes from 'prop-types'
import GenericTable from '../../../common/GenericTable'
import SortableTh from '../../../../../../common/Table/SortableTh'
class ReceiverFormTable extends GenericTable {
static propTypes = {
t: PropTypes.func.isRequired,
tableState: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
tableActions: PropTypes.object.isRequired,
receiver: PropTypes.object.isRequired
};
fetchData = (page, pageSize, sorted) => {
const { tableActions, receiver } = this.props
const params = {
page: page + 1,
limit: pageSize
}
if (sorted.length) {
const sortedField = sorted[0]
params['sortField'] = sortedField.id
params['sortDirection'] = sortedField.desc ? 'desc' : 'asc'
}
tableActions.loadTable(params, receiver)
};
defineColumns () {
const {t} = this.props
const colDefs = super.defineColumns()
return {
...colDefs,
'active': {
Header: <SortableTh title='notificationsTab.status' />,
accessor: item => item.active ? t('notificationsTab.active') : t('notificationsTab.paused'),
width: 100
}
}
}
}
export default ReceiverFormTable
@@ -0,0 +1,108 @@
import React from 'react'
import PropTypes from 'prop-types'
import {translate} from 'react-i18next'
import ReceiverFormTable from './ReceiverFormTable'
import SortableTh from '../../../../../../common/Table/SortableTh'
import LinkCell from '../../../../../../common/Table/LinkCell'
import FormTableTopBar from './FormTableTopBar'
export class ReceiverGroupsTable extends ReceiverFormTable {
static propTypes = {
t: PropTypes.func.isRequired,
tableState: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
tableActions: PropTypes.object.isRequired,
receiver: PropTypes.object.isRequired,
formActions: PropTypes.object.isRequired
};
togglerOnAction = (itemId) => {
this.props.formActions.toggleGroup(itemId, true)
this.props.tableActions.toggleEnrolled(itemId, true)
};
togglerOffAction = (itemId) => {
this.props.formActions.toggleGroup(itemId, false)
this.props.tableActions.toggleEnrolled(itemId, false)
};
_formatSubscriptions (subscriptions) {
console.log('format subsc', subscriptions)
const result = []
if (subscriptions.alert > 0) {
result.push(`${subscriptions.alert} Alerts`)
}
if (subscriptions.newsletter > 0) {
result.push(`${subscriptions.newsletter} Newsletters`)
}
return result.join(', ')
};
_formatRecipients (number) {
if (number) {
if (number === 1) {
return '1 Recipient'
} else {
return number + ' Recipients'
}
}
return ''
}
defineColumns () {
const {t} = this.props
return {
...super.defineColumns(),
'groupName': {
Header: <SortableTh title='manageRecipientsTab.groupName' />,
accessor: 'name',
Cell: (row) => {
return (
<LinkCell item={row.original} onClick={this.nameClickAction}>
{row.value}
</LinkCell>
)
}
},
'enrolled': this.createTogglerColumn('manageRecipientsTab.form.recipient.enroll', 'enrolled', 'yes', 'no', this.togglerOnAction, this.togglerOffAction),
'subscriptions': {
sortable: false,
Header: t('manageRecipientsTab.subscriptions'),
accessor: item => this._formatSubscriptions(item.subscriptions),
width: 170
},
'recipients': {
sortable: false,
Header: t('manageRecipientsTab.recipients'),
accessor: item => this._formatRecipients(item.recipients.length),
width: 170
}
}
}
getColumns () {
return ['groupName', 'subscriptions', 'recipients', 'active', 'enrolled']
}
noCard () {
return true
}
getActionsPanel () {
const {tableState, tableActions, receiver} = this.props
return (
<FormTableTopBar
tableActions={tableActions}
statusFilter={tableState.statusFilter}
receiver={receiver}
type="groups"
yesText="Enrolled"
noText="NotEnrolled"
allText="All"
/>
)
}
}
export default translate(['tabsContent'], { wait: true })(ReceiverGroupsTable)
@@ -0,0 +1,75 @@
import React from 'react'
import PropTypes from 'prop-types'
import {translate} from 'react-i18next'
import ReceiverFormTable from './ReceiverFormTable'
import SortableTh from '../../../../../../common/Table/SortableTh'
import FormTableTopBar from './FormTableTopBar'
import { convertUTCtoLocal } from '../../../../../../../common/helper'
export class ReceiverRecipientsTable extends ReceiverFormTable {
static propTypes = {
t: PropTypes.func.isRequired,
tableState: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
tableActions: PropTypes.object.isRequired,
receiver: PropTypes.object.isRequired,
formActions: PropTypes.object.isRequired
};
togglerOnAction = (itemId) => {
this.props.formActions.toggleRecipient(itemId, true)
this.props.tableActions.toggleEnrolled(itemId, true)
};
togglerOffAction = (itemId) => {
this.props.formActions.toggleRecipient(itemId, false)
this.props.tableActions.toggleEnrolled(itemId, false)
};
defineColumns () {
const {t} = this.props
return {
...super.defineColumns(),
'enrolled': this.createTogglerColumn('manageRecipientsTab.form.recipient.enroll', 'enrolled', 'yes', 'no', this.togglerOnAction, this.togglerOffAction),
'name': {
Header: <SortableTh title='manageRecipientsTab.name' />,
accessor: item => `${item.firstName} ${item.lastName}`
},
'email': {
Header: <SortableTh title='manageRecipientsTab.email' />,
accessor: 'email',
width: 170
},
'addedDate': {
Header: t('manageRecipientsTab.form.group.addedDate'),
accessor: item => item.creationDate ? convertUTCtoLocal(item.creationDate, 'DD MMM YYYY HH:mm') : '',
width: 170
}
}
}
getColumns () {
return ['name', 'email', 'addedDate', 'active', 'enrolled']
}
noCard () {
return true
}
getActionsPanel () {
const {tableState, tableActions, receiver} = this.props
return (
<FormTableTopBar
tableActions={tableActions}
statusFilter={tableState.statusFilter}
receiver={receiver}
type="recipients"
yesText="Enrolled"
noText="NotEnrolled"
allText="All"
/>
)
}
}
export default translate(['tabsContent'], { wait: true })(ReceiverRecipientsTable)
@@ -0,0 +1,58 @@
import React from 'react'
import PropTypes from 'prop-types'
import {translate} from 'react-i18next'
import ReceiverFormTable from './ReceiverFormTable'
import FormTableTopBar from './FormTableTopBar'
export class ReceiverSubscriptionsTable extends ReceiverFormTable {
static propTypes = {
t: PropTypes.func.isRequired,
tableState: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired,
tableActions: PropTypes.object.isRequired,
receiver: PropTypes.object.isRequired,
formActions: PropTypes.object.isRequired
};
togglerOnAction = (itemId) => {
this.props.formActions.toggleSubscription(itemId, true)
this.props.tableActions.toggleSubscribed(itemId, true)
};
togglerOffAction = (itemId) => {
this.props.formActions.toggleSubscription(itemId, false)
this.props.tableActions.toggleSubscribed(itemId, false)
};
defineColumns () {
return {
...super.defineColumns(),
'subscribed': this.createTogglerColumn('notificationsTab.action', 'subscribed', 'subscribed', 'unsubscribed', this.togglerOnAction, this.togglerOffAction)
}
}
getColumns () {
return ['name', 'type', 'ScheduledTimes', 'active', 'subscribed']
}
noCard () {
return true
}
getActionsPanel () {
const {tableState, tableActions, receiver} = this.props
return (
<FormTableTopBar
tableActions={tableActions}
statusFilter={tableState.statusFilter}
receiver={receiver}
type="subscriptions"
yesText="Subscribed"
noText="Unsubscribed"
allText="All"
/>
)
}
}
export default translate(['tabsContent'], { wait: true })(ReceiverSubscriptionsTable)