Namespace Filter
This commit is contained in:
parent
6b6fa8b3ef
commit
8d58c3d282
45 changed files with 783 additions and 158 deletions
|
@ -22,7 +22,7 @@ import {
|
|||
withFormErrorHandlers
|
||||
} from '../lib/form';
|
||||
import {withAsyncErrorHandler, withErrorHandling} from '../lib/error-handling';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace} from '../lib/namespace';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace, getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
import {DeleteModalDialog} from "../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {getTagLanguages, getTemplateTypes, getTypeForm, ResourceType} from '../templates/helpers';
|
||||
|
@ -529,7 +529,7 @@ export default class CUD extends Component {
|
|||
const canDelete = isEdit && this.props.entity.permissions.includes('delete');
|
||||
|
||||
let extraSettings = null;
|
||||
|
||||
|
||||
const sourceTypeKey = Number.parseInt(this.getFormValue('source'));
|
||||
const campaignTypeKey = this.getFormValue('type');
|
||||
|
||||
|
@ -557,6 +557,10 @@ export default class CUD extends Component {
|
|||
const lstOrderIdxClosure = lstOrderIdx;
|
||||
|
||||
const selectedList = this.getFormValue(prefix + 'list');
|
||||
var listsTable = <TableSelect id={prefix + 'list'} label={t('list')} withHeader dropdown dataUrl='rest/lists-table' columns={listsColumns} selectionLabelIndex={1} />;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
listsTable = <TableSelect id={prefix + 'list'} label={t('list')} withHeader dropdown dataUrl={'rest/lists-table/'+ getNamespaceIdFilterCookie()} columns={listsColumns} selectionLabelIndex={1} />;
|
||||
}
|
||||
|
||||
lstsEditEntries.push(
|
||||
<div key={lstUid} className={campaignsStyles.entry + ' ' + campaignsStyles.entryWithButtons}>
|
||||
|
@ -593,7 +597,8 @@ export default class CUD extends Component {
|
|||
}
|
||||
</div>
|
||||
<div className={campaignsStyles.entryContent}>
|
||||
<TableSelect id={prefix + 'list'} label={t('list')} withHeader dropdown dataUrl='rest/lists-table' columns={listsColumns} selectionLabelIndex={1} />
|
||||
|
||||
{listsTable}
|
||||
|
||||
{(campaignTypeKey === CampaignType.REGULAR || campaignTypeKey === CampaignType.RSS) &&
|
||||
<div>
|
||||
|
@ -697,6 +702,9 @@ export default class CUD extends Component {
|
|||
// The "key" property here and in the TableSelect below is to tell React that these tables are different and should be rendered by different instances. Otherwise, React will use
|
||||
// only one instance, which fails because Table does not handle updates in "columns" property
|
||||
templateEdit = <TableSelect key="templateSelect" id="data_sourceTemplate" label={t('template')} withHeader dropdown dataUrl='rest/templates-table' columns={templatesColumns} selectionLabelIndex={1} help={help}/>;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
templateEdit = <TableSelect key="templateSelect" id="data_sourceTemplate" label={t('template')} withHeader dropdown dataUrl={'rest/templates-table/'+getNamespaceIdFilterCookie()} columns={templatesColumns} selectionLabelIndex={1} help={help}/>;
|
||||
}
|
||||
|
||||
} else if (!isEdit && sourceTypeKey === CampaignSource.CUSTOM_FROM_CAMPAIGN) {
|
||||
const campaignsColumns = [
|
||||
|
@ -707,9 +715,10 @@ export default class CUD extends Component {
|
|||
{ data: 5, title: t('created'), render: data => moment(data).fromNow() },
|
||||
{ data: 6, title: t('namespace') }
|
||||
];
|
||||
|
||||
templateEdit = <TableSelect key="campaignSelect" id="data_sourceCampaign" label={t('campaign')} withHeader dropdown dataUrl='rest/campaigns-with-content-table' columns={campaignsColumns} selectionLabelIndex={1} help={t('contentOfTheSelectedCampaignWillBeCopied')}/>;
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
templateEdit = <TableSelect key="campaignSelect" id="data_sourceCampaign" label={t('campaign')} withHeader dropdown dataUrl={'rest/campaigns-with-content-table/' + getNamespaceIdFilterCookie()} columns={campaignsColumns} selectionLabelIndex={1} help={t('contentOfTheSelectedCampaignWillBeCopied')}/>;
|
||||
}
|
||||
} else if (!isEdit && sourceTypeKey === CampaignSource.CUSTOM) {
|
||||
const customTemplateTypeKey = this.getFormValue('data_sourceCustom_type');
|
||||
|
||||
|
@ -730,6 +739,12 @@ export default class CUD extends Component {
|
|||
templateEdit = <InputField id="data_sourceUrl" label={t('renderUrl')} help={t('ifAMessageIsSentThenThisUrlWillBePosTed')}/>
|
||||
}
|
||||
|
||||
var sendConfigTable = <TableSelect id="send_configuration" label={t('sendConfiguration')} withHeader dropdown dataUrl='rest/send-configurations-table' columns={sendConfigurationsColumns} selectionLabelIndex={1} />;
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
sendConfigTable = <TableSelect id="send_configuration" label={t('sendConfiguration')} withHeader dropdown dataUrl={'rest/send-configurations-table/' + getNamespaceIdFilterCookie()} columns={sendConfigurationsColumns} selectionLabelIndex={1} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{canDelete &&
|
||||
|
@ -773,8 +788,8 @@ export default class CUD extends Component {
|
|||
<hr/>
|
||||
|
||||
<Fieldset label={t('sendSettings')}>
|
||||
|
||||
<TableSelect id="send_configuration" label={t('sendConfiguration')} withHeader dropdown dataUrl='rest/send-configurations-table' columns={sendConfigurationsColumns} selectionLabelIndex={1} />
|
||||
|
||||
{sendConfigTable}
|
||||
|
||||
{sendSettings}
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@ import {CampaignSource, CampaignStatus, CampaignType} from "../../../shared/camp
|
|||
import {getCampaignLabels} from "./helpers";
|
||||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import {getNamespaceIdFilterCookie} from "../lib/namespace";
|
||||
import styles from "./styles.scss";
|
||||
import PropTypes from 'prop-types';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -137,6 +139,10 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var campaingsTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/campaigns-table"} columns={columns} />;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
campaingsTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/campaigns-table/" + getNamespaceIdFilterCookie()} columns={columns} />;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -152,7 +158,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('campaigns')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/campaigns-table" columns={columns} />
|
||||
{campaingsTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import React, {Component} from 'react';
|
|||
import {withTranslation} from './i18n';
|
||||
import {TreeTableSelect} from './form';
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
|
@ -12,7 +13,11 @@ import {withComponentMixins} from "./decorator-helpers";
|
|||
export class NamespaceSelect extends Component {
|
||||
render() {
|
||||
const t = this.props.t;
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
return (
|
||||
<TreeTableSelect id="namespace" label={t('namespace')} dataUrl={"rest/namespaces-tree/" + getNamespaceIdFilterCookie()}/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TreeTableSelect id="namespace" label={t('namespace')} dataUrl="rest/namespaces-tree"/>
|
||||
);
|
||||
|
@ -27,10 +32,34 @@ export function validateNamespace(t, state) {
|
|||
}
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var decodedCookie = decodeURIComponent(document.cookie);
|
||||
var ca = decodedCookie.split(';');
|
||||
for(var i = 0; i <ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export function getDefaultNamespace(permissions) {
|
||||
return permissions.viewUsersNamespace && permissions.createEntityInUsersNamespace ? mailtrainConfig.user.namespace : null;
|
||||
}
|
||||
|
||||
export function getNamespaceIdFilterCookie() {
|
||||
return getCookie("namespaceFilterId");
|
||||
}
|
||||
|
||||
export function getNamespaceNameFilterCookie() {
|
||||
return getCookie("namespaceFilterName");
|
||||
}
|
||||
|
||||
export function namespaceCheckPermissions(createOperation) {
|
||||
if (mailtrainConfig.user) {
|
||||
return {
|
||||
|
|
|
@ -22,11 +22,12 @@ import {
|
|||
} from '../lib/form';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import {DeleteModalDialog} from '../lib/modals';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace} from '../lib/namespace';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace, getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
import {FieldWizard, UnsubscriptionMode} from '../../../shared/lists';
|
||||
import styles from "../lib/styles.scss";
|
||||
import {getMailerTypes} from "../send-configurations/helpers";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -239,6 +240,12 @@ export default class CUD extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
var sendConfigTable = <TableSelect id="send_configuration" label={t('sendConfiguration')} withHeader dropdown dataUrl='rest/send-configurations-table' columns={sendConfigurationsColumns} selectionLabelIndex={1} help={t('sendConfigurationThatWillBeUsedFor')}/>
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
sendConfigTable = <TableSelect id="send_configuration" label={t('sendConfiguration')} withHeader dropdown dataUrl={'rest/send-configurations-table/' + getNamespaceIdFilterCookie()} columns={sendConfigurationsColumns} selectionLabelIndex={1} help={t('sendConfigurationThatWillBeUsedFor')}/>
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{canDelete &&
|
||||
|
@ -268,8 +275,9 @@ export default class CUD extends Component {
|
|||
<InputField id="contact_email" label={t('contactEmail')} help={t('contactEmailUsedInSubscriptionFormsAnd')}/>
|
||||
<InputField id="homepage" label={t('homepage')} help={t('homepageUrlUsedInSubscriptionFormsAnd')}/>
|
||||
{toNameFields}
|
||||
<TableSelect id="send_configuration" label={t('sendConfiguration')} withHeader dropdown dataUrl='rest/send-configurations-table' columns={sendConfigurationsColumns} selectionLabelIndex={1} help={t('sendConfigurationThatWillBeUsedFor')}/>
|
||||
|
||||
{sendConfigTable}
|
||||
|
||||
<NamespaceSelect/>
|
||||
|
||||
<Dropdown id="form" label={t('forms')} options={formsOptions} help={t('webAndEmailFormsAndTemplatesUsedIn')}/>
|
||||
|
|
|
@ -9,7 +9,9 @@ import {Icon} from "../lib/bootstrap-components";
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import {withForm} from "../lib/form";
|
||||
import {getNamespaceIdFilterCookie} from "../lib/namespace";
|
||||
import PropTypes from 'prop-types';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -116,6 +118,11 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var listsTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/lists-table" columns={columns} />;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
listsTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/lists-table/" + getNamespaceIdFilterCookie()} columns={columns} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -130,7 +137,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('lists')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/lists-table" columns={columns} />
|
||||
{listsTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
withFormErrorHandlers
|
||||
} from '../../lib/form';
|
||||
import {withErrorHandling} from '../../lib/error-handling';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace} from '../../lib/namespace';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace, getNamespaceIdFilterCookie} from '../../lib/namespace';
|
||||
import {DeleteModalDialog} from "../../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {getTrustedUrl, getUrl} from "../../lib/urls";
|
||||
|
@ -486,6 +486,13 @@ export default class CUD extends Component {
|
|||
const previewListId = this.getFormValue('previewList');
|
||||
const selectedTemplate = this.getFormValue('selectedTemplate');
|
||||
|
||||
var customFormsTable = <TableSelect id="existingEntity" label={t('Source custom forms')} withHeader dropdown dataUrl='rest/forms-table' columns={customFormsColumns} selectionLabelIndex={1} />;
|
||||
var listsTable = <TableSelect id="previewList" label={t('listToPreviewOn')} withHeader dropdown dataUrl='rest/lists-table' columns={listsColumns} selectionLabelIndex={1} help={t('selectListWhoseFieldsWillBeUsedToPreview')}/>;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
customFormsTable = <TableSelect id="existingEntity" label={t('Source custom forms')} withHeader dropdown dataUrl={'rest/forms-table/' +getNamespaceIdFilterCookie()} columns={customFormsColumns} selectionLabelIndex={1} />;
|
||||
listsTable = <TableSelect id="previewList" label={t('listToPreviewOn')} withHeader dropdown dataUrl={'rest/lists-table/' + getNamespaceIdFilterCookie()} columns={listsColumns} selectionLabelIndex={1} help={t('selectListWhoseFieldsWillBeUsedToPreview')}/>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={this.state.previewFullscreen ? styles.withElementInFullscreen : ''}>
|
||||
{canDelete &&
|
||||
|
@ -512,12 +519,12 @@ export default class CUD extends Component {
|
|||
<CheckBox id="fromExistingEntity" label={t('customForms')} text={t('cloneFromAnExistingCustomForms')}/>
|
||||
}
|
||||
|
||||
{this.getFormValue('fromExistingEntity') ?
|
||||
<TableSelect id="existingEntity" label={t('Source custom forms')} withHeader dropdown dataUrl='rest/forms-table' columns={customFormsColumns} selectionLabelIndex={1} />
|
||||
:
|
||||
{this.getFormValue('fromExistingEntity') && customFormsTable}
|
||||
|
||||
{!this.getFormValue('fromExistingEntity') &&
|
||||
<>
|
||||
<Fieldset label={t('formsPreview')}>
|
||||
<TableSelect id="previewList" label={t('listToPreviewOn')} withHeader dropdown dataUrl='rest/lists-table' columns={listsColumns} selectionLabelIndex={1} help={t('selectListWhoseFieldsWillBeUsedToPreview')}/>
|
||||
{listsTable}
|
||||
|
||||
{ previewListId &&
|
||||
<div>
|
||||
|
|
|
@ -9,6 +9,8 @@ import {Icon} from "../../lib/bootstrap-components";
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
import PropTypes from 'prop-types';
|
||||
import {getNamespaceIdFilterCookie} from '../../lib/namespace';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -62,7 +64,10 @@ export default class List extends Component {
|
|||
}
|
||||
}
|
||||
];
|
||||
|
||||
var customFormsTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/forms-table" columns={columns} />;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
customFormsTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/forms-table/" + getNamespaceIdFilterCookie()} columns={columns} />;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -74,7 +79,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('forms')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/forms-table" columns={columns} />
|
||||
{customFormsTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
174
client/src/namespaces/Filter.js
Normal file
174
client/src/namespaces/Filter.js
Normal file
|
@ -0,0 +1,174 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {requiresAuthenticatedUser, Title, withPageHelpers} from '../lib/page';
|
||||
import {
|
||||
Button,
|
||||
ButtonRow,
|
||||
filterData,
|
||||
Form,
|
||||
FormSendMethod,
|
||||
TreeTableSelect,
|
||||
withForm,
|
||||
withFormErrorHandlers
|
||||
} from '../lib/form';
|
||||
import axios from '../lib/axios';
|
||||
import {withAsyncErrorHandler, withErrorHandling} from '../lib/error-handling';
|
||||
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import {getDefaultNamespace} from "../lib/namespace";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Filter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {};
|
||||
|
||||
this.initForm();
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
action: PropTypes.string.isRequired,
|
||||
entity: PropTypes.object,
|
||||
permissions: PropTypes.object
|
||||
}
|
||||
|
||||
submitFormValuesMutator(data) {
|
||||
return filterData(data, ['name', 'description', 'namespace']);
|
||||
}
|
||||
|
||||
isEditGlobal() {
|
||||
return this.props.entity && this.props.entity.id === getGlobalNamespaceId();
|
||||
}
|
||||
|
||||
removeNsIdSubtree(data) {
|
||||
for (let idx = 0; idx < data.length; idx++) {
|
||||
const entry = data[idx];
|
||||
|
||||
if (entry.key === this.props.entity.id) {
|
||||
data.splice(idx, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.removeNsIdSubtree(entry.children)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@withAsyncErrorHandler
|
||||
async loadTreeData() {
|
||||
if (!this.isEditGlobal()) {
|
||||
const response = await axios.get(getUrl('rest/namespaces-tree'));
|
||||
const data = response.data;
|
||||
for (const root of data) {
|
||||
root.expanded = true;
|
||||
}
|
||||
|
||||
if (this.props.entity && !this.isEditGlobal()) {
|
||||
this.removeNsIdSubtree(data);
|
||||
}
|
||||
|
||||
if (this.isComponentMounted()) {
|
||||
this.setState({
|
||||
treeData: data
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.entity) {
|
||||
this.getFormValuesFromEntity(this.props.entity);
|
||||
} else {
|
||||
this.populateFormValues({
|
||||
name: '',
|
||||
description: '',
|
||||
namespace: getDefaultNamespace(this.props.permissions)
|
||||
});
|
||||
}
|
||||
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
this.loadTreeData();
|
||||
}
|
||||
|
||||
localValidateFormValues(state) {
|
||||
const t = this.props.t;
|
||||
|
||||
if (!state.getIn(['namespace', 'value'])) {
|
||||
state.setIn(['namespace', 'error'], t('namespaceMustBeSelected'));
|
||||
} else {
|
||||
state.setIn(['namespace', 'error'], null);
|
||||
}
|
||||
}
|
||||
|
||||
@withFormErrorHandlers
|
||||
async submitHandler(leave, disallow) {
|
||||
|
||||
if(disallow){
|
||||
document.cookie = 'namespaceFilterId' + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';//Delete namespaceFilter cookies
|
||||
document.cookie = 'namespaceFilterName' + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
location.reload();
|
||||
}else{
|
||||
const t = this.props.t;
|
||||
|
||||
let sendMethod, url;
|
||||
sendMethod = FormSendMethod.GET;
|
||||
|
||||
if(this.getFormValue('namespace')){
|
||||
url = 'rest/namespaces/' + this.getFormValue('namespace');
|
||||
this.disableForm();
|
||||
this.setFormStatusMessage('info', t('selecting'));
|
||||
const submitResult = await this.validateAndSendFormValuesToURL(sendMethod, url);
|
||||
document.cookie = "namespaceFilterId=" + this.getFormValue('namespace') + ";";
|
||||
document.cookie = "namespaceFilterName=" + submitResult.name + ";";
|
||||
|
||||
if (submitResult) {
|
||||
if(leave) {
|
||||
history.back();
|
||||
}else{
|
||||
location.reload();
|
||||
}
|
||||
}else {
|
||||
this.enableForm();
|
||||
this.setFormStatusMessage('warning', t('thereAreErrorsInTheFormPleaseFixThemAnd'));
|
||||
}
|
||||
}else{
|
||||
this.setFormStatusMessage('warning', t('namespaceMustBeSelected'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const t = this.props.t;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
<Title>{t('namespaceFilter')}</Title>
|
||||
|
||||
<Form stateOwner={this} onSubmitAsync={::this.submitHandler}>
|
||||
|
||||
<TreeTableSelect id="namespace" label={t('namespace')} data={this.state.treeData}/>
|
||||
|
||||
<ButtonRow>
|
||||
<Button type="submit" className="btn-primary" icon="check" label={t('select')} onClickAsync={async () => await this.submitHandler(false,false)}/>
|
||||
<Button type="submit" className="btn-primary" icon="check" label={t('selectAndReturn')} onClickAsync={async () => await this.submitHandler(true, false)}/>
|
||||
<Button type="submit" className="btn-danger" icon="times" label={t('disallow')} onClickAsync={async () => await this.submitHandler(null,true)}/>
|
||||
</ButtonRow>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
|||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import PropTypes from 'prop-types';
|
||||
import {getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -61,6 +62,12 @@ export default class List extends Component {
|
|||
return actions;
|
||||
};
|
||||
|
||||
var namespacesTree = <TreeTable ref={node => this.table = node} withHeader withDescription dataUrl="rest/namespaces-tree" actions={actions} />
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
namespacesTree = <TreeTable ref={node => this.table = node} withHeader withDescription dataUrl={"rest/namespaces-tree/" + getNamespaceIdFilterCookie()} actions={actions} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -72,7 +79,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('namespaces')}</Title>
|
||||
|
||||
<TreeTable ref={node => this.table = node} withHeader withDescription dataUrl="rest/namespaces-tree" actions={actions} />
|
||||
{namespacesTree}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,54 +1,106 @@
|
|||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import CUD from './CUD';
|
||||
import List from './List';
|
||||
import CUD from "./CUD";
|
||||
import List from './List'
|
||||
import Filter from "./Filter";
|
||||
import Share from '../shares/Share';
|
||||
import {ellipsizeBreadcrumbLabel} from "../lib/helpers";
|
||||
import {namespaceCheckPermissions} from "../lib/namespace";
|
||||
import mailtrainConfig from "mailtrainConfig";
|
||||
|
||||
function getMenus(t) {
|
||||
return {
|
||||
namespaces: {
|
||||
title: t('namespaces'),
|
||||
link: '/namespaces',
|
||||
checkPermissions: {
|
||||
createNamespace: {
|
||||
entityTypeId: 'namespace',
|
||||
requiredOperations: ['createNamespace']
|
||||
},
|
||||
...namespaceCheckPermissions('createNamespace')
|
||||
},
|
||||
panelRender: props => <List permissions={props.permissions}/>,
|
||||
children: {
|
||||
':namespaceId([0-9]+)': {
|
||||
title: resolved => t('namespaceName', {name: ellipsizeBreadcrumbLabel(resolved.namespace.name)}),
|
||||
resolve: {
|
||||
namespace: params => `rest/namespaces/${params.namespaceId}`
|
||||
if(mailtrainConfig.namespaceFilterEnabled){
|
||||
return {
|
||||
namespaces: {
|
||||
title: t('namespaces'),
|
||||
link: '/namespaces',
|
||||
checkPermissions: {
|
||||
createNamespace: {
|
||||
entityTypeId: 'namespace',
|
||||
requiredOperations: ['createNamespace']
|
||||
},
|
||||
link: params => `/namespaces/${params.namespaceId}/edit`,
|
||||
navs: {
|
||||
':action(edit|delete)': {
|
||||
title: t('edit'),
|
||||
link: params => `/namespaces/${params.namespaceId}/edit`,
|
||||
visible: resolved => resolved.namespace.permissions.includes('edit'),
|
||||
panelRender: props => <CUD action={props.match.params.action} entity={props.resolved.namespace} permissions={props.permissions} />
|
||||
...namespaceCheckPermissions('createNamespace')
|
||||
},
|
||||
panelRender: props => <List permissions={props.permissions}/>,
|
||||
children: {
|
||||
':namespaceId([0-9]+)': {
|
||||
title: resolved => t('namespaceName', {name: ellipsizeBreadcrumbLabel(resolved.namespace.name)}),
|
||||
resolve: {
|
||||
namespace: params => `rest/namespaces/${params.namespaceId}`
|
||||
},
|
||||
share: {
|
||||
title: t('share'),
|
||||
link: params => `/namespaces/${params.namespaceId}/share`,
|
||||
visible: resolved => resolved.namespace.permissions.includes('share'),
|
||||
panelRender: props => <Share title={t('share')} entity={props.resolved.namespace} entityTypeId="namespace" />
|
||||
link: params => `/namespaces/${params.namespaceId}/edit`,
|
||||
navs: {
|
||||
':action(edit|delete)': {
|
||||
title: t('edit'),
|
||||
link: params => `/namespaces/${params.namespaceId}/edit`,
|
||||
visible: resolved => resolved.namespace.permissions.includes('edit'),
|
||||
panelRender: props => <CUD action={props.match.params.action} entity={props.resolved.namespace} permissions={props.permissions} />
|
||||
},
|
||||
share: {
|
||||
title: t('share'),
|
||||
link: params => `/namespaces/${params.namespaceId}/share`,
|
||||
visible: resolved => resolved.namespace.permissions.includes('share'),
|
||||
panelRender: props => <Share title={t('share')} entity={props.resolved.namespace} entityTypeId="namespace" />
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
create: {
|
||||
title: t('create'),
|
||||
panelRender: props => <CUD action="create" permissions={props.permissions} />
|
||||
},
|
||||
},
|
||||
filter: {
|
||||
title: t('filter'),
|
||||
panelRender: props => <Filter action="filter" permissions={props.permissions} />
|
||||
},
|
||||
create: {
|
||||
title: t('create'),
|
||||
panelRender: props => <CUD action="create" permissions={props.permissions} />
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
else{
|
||||
return {
|
||||
namespaces: {
|
||||
title: t('namespaces'),
|
||||
link: '/namespaces',
|
||||
checkPermissions: {
|
||||
createNamespace: {
|
||||
entityTypeId: 'namespace',
|
||||
requiredOperations: ['createNamespace']
|
||||
},
|
||||
...namespaceCheckPermissions('createNamespace')
|
||||
},
|
||||
panelRender: props => <List permissions={props.permissions}/>,
|
||||
children: {
|
||||
':namespaceId([0-9]+)': {
|
||||
title: resolved => t('namespaceName', {name: ellipsizeBreadcrumbLabel(resolved.namespace.name)}),
|
||||
resolve: {
|
||||
namespace: params => `rest/namespaces/${params.namespaceId}`
|
||||
},
|
||||
link: params => `/namespaces/${params.namespaceId}/edit`,
|
||||
navs: {
|
||||
':action(edit|delete)': {
|
||||
title: t('edit'),
|
||||
link: params => `/namespaces/${params.namespaceId}/edit`,
|
||||
visible: resolved => resolved.namespace.permissions.includes('edit'),
|
||||
panelRender: props => <CUD action={props.match.params.action} entity={props.resolved.namespace} permissions={props.permissions} />
|
||||
},
|
||||
share: {
|
||||
title: t('share'),
|
||||
link: params => `/namespaces/${params.namespaceId}/share`,
|
||||
visible: resolved => resolved.namespace.permissions.includes('share'),
|
||||
panelRender: props => <Share title={t('share')} entity={props.resolved.namespace} entityTypeId="namespace" />
|
||||
}
|
||||
}
|
||||
},
|
||||
create: {
|
||||
title: t('create'),
|
||||
panelRender: props => <CUD action="create" permissions={props.permissions} />
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ import {getDefaultNamespace, NamespaceSelect, validateNamespace} from '../lib/na
|
|||
import {DeleteModalDialog} from "../lib/modals";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import {getNamespaceIdFilterCookie} from "../lib/namespace";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
|
|
@ -13,6 +13,8 @@ import {getUrl} from "../lib/urls";
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import PropTypes from 'prop-types';
|
||||
import {getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -147,6 +149,11 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var reportsTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/reports-table" columns={columns} />;
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
reportsTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/reports-table/" + getNamespaceIdFilterCookie()} columns={columns} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -162,7 +169,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('reports')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/reports-table" columns={columns} />
|
||||
{reportsTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import mailtrainConfig from 'mailtrainConfig';
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
import PropTypes from 'prop-types';
|
||||
import {getNamespaceIdFilterCookie} from '../../lib/namespace';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -67,6 +68,12 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var reportTemplatesTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/report-templates-table" columns={columns} />
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
reportTemplatesTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/report-templates-table/" + getNamespaceIdFilterCookie()} columns={columns} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -82,8 +89,7 @@ export default class List extends Component {
|
|||
}
|
||||
|
||||
<Title>{t('reportTemplates')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/report-templates-table" columns={columns} />
|
||||
{reportTemplatesTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ import users from './users/root';
|
|||
import sendConfigurations from './send-configurations/root';
|
||||
import settings from './settings/root';
|
||||
|
||||
import {DropdownLink, getLanguageChooser, NavDropdown, NavLink, Section} from "./lib/page";
|
||||
import {DropdownLink, getLanguageChooser, getNamespaceChooser, NavDropdown, NavLink, Section} from "./lib/page";
|
||||
import {getNamespaceNameFilterCookie} from "./lib/namespace";
|
||||
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import Home from "./Home";
|
||||
|
@ -56,6 +57,10 @@ class Root extends Component {
|
|||
async logout() {
|
||||
await axios.post(getUrl('rest/logout'));
|
||||
window.location = getUrl();
|
||||
if(mailtrainConfig.namespaceFilterEnabled){
|
||||
document.cookie = 'namespaceFilterId' + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';//Delete namespaceFilter cookies
|
||||
document.cookie = 'namespaceFilterName' + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -64,7 +69,17 @@ class Root extends Component {
|
|||
const topLevelItems = structure.children;
|
||||
|
||||
const topLevelMenu = [];
|
||||
|
||||
var namespaceFilter = null;
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled){
|
||||
if(getNamespaceNameFilterCookie()){
|
||||
namespaceFilter = <NavLink to={'/namespaces/filter'}>{getNamespaceNameFilterCookie()}</NavLink>;
|
||||
}else{
|
||||
namespaceFilter = <NavLink to={'/namespaces/filter'}>{'Namespace filter'}</NavLink>;
|
||||
}
|
||||
}
|
||||
|
||||
for (const entryKey of topLevelMenuKeys) {
|
||||
const entry = topLevelItems[entryKey];
|
||||
const link = entry.link || entry.externalLink;
|
||||
|
@ -91,6 +106,7 @@ class Root extends Component {
|
|||
</NavDropdown>
|
||||
</ul>
|
||||
<ul className="navbar-nav mt-navbar-nav-right">
|
||||
{namespaceFilter}
|
||||
{getLanguageChooser(t)}
|
||||
<NavDropdown menuClassName="dropdown-menu-right" label={mailtrainConfig.user.username} icon="user">
|
||||
<DropdownLink to="/account"><Icon icon='user'/> {t('account')}</DropdownLink>
|
||||
|
|
|
@ -11,6 +11,8 @@ import {getMailerTypes} from './helpers';
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import PropTypes from 'prop-types';
|
||||
import {getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
|
@ -72,6 +74,12 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var sendConfigTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/send-configurations-table" columns={columns} />
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
sendConfigTable = <Table ref={node => this.table = node} withHeader dataUrl={'rest/send-configurations-table/' + getNamespaceIdFilterCookie()} columns={columns} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -83,7 +91,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('sendConfigurations-1')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/send-configurations-table" columns={columns} />
|
||||
{sendConfigTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
withFormErrorHandlers
|
||||
} from '../lib/form';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace} from '../lib/namespace';
|
||||
import {getDefaultNamespace, NamespaceSelect, validateNamespace, getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
import {ContentModalDialog, DeleteModalDialog} from "../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {getEditForm, getTagLanguages, getTemplateTypes, getTypeForm} from './helpers';
|
||||
|
@ -325,6 +325,12 @@ export default class CUD extends Component {
|
|||
{ data: 6, title: t('namespace') },
|
||||
];
|
||||
|
||||
var sourceTemplateTable = <TableSelect id="existingEntity" label={t('Source template')} withHeader dropdown dataUrl='rest/templates-table' columns={templatesColumns} selectionLabelIndex={1} />;
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
sourceTemplateTable = <TableSelect id="existingEntity" label={t('Source template')} withHeader dropdown dataUrl={'rest/templates-table/'+getNamespaceIdFilterCookie()} columns={templatesColumns} selectionLabelIndex={1} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={this.state.elementInFullscreen ? styles.withElementInFullscreen : ''}>
|
||||
{isEdit &&
|
||||
|
@ -362,9 +368,9 @@ export default class CUD extends Component {
|
|||
<CheckBox id="fromExistingEntity" label={t('template')} text={t('cloneFromAnExistingTemplate')}/>
|
||||
}
|
||||
|
||||
{this.getFormValue('fromExistingEntity') ?
|
||||
<TableSelect id="existingEntity" label={t('Source template')} withHeader dropdown dataUrl='rest/templates-table' columns={templatesColumns} selectionLabelIndex={1} />
|
||||
:
|
||||
{this.getFormValue('fromExistingEntity') && sourceTemplateTable }
|
||||
|
||||
{!this.getFormValue('fromExistingEntity') &&
|
||||
<>
|
||||
{isEdit ?
|
||||
<StaticField id="type" className={styles.formDisabled} label={t('type')}>
|
||||
|
|
|
@ -11,7 +11,8 @@ import {getTagLanguages, getTemplateTypes} from './helpers';
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {getNamespaceIdFilterCookie} from "../lib/namespace";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -81,6 +82,11 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var templatesTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/templates-table" columns={columns} />;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
templatesTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/templates-table/" + getNamespaceIdFilterCookie()} columns={columns} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -95,7 +101,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('templates')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/templates-table" columns={columns} />
|
||||
{templatesTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import {Trans} from "react-i18next";
|
|||
import {TagLanguages, renderTag} from "../../../shared/templates";
|
||||
|
||||
import styles from "../lib/styles.scss";
|
||||
import {getNamespaceIdFilterCookie } from "../lib/namespace";
|
||||
|
||||
export const ResourceType = {
|
||||
TEMPLATE: 'template',
|
||||
|
@ -89,7 +90,18 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
getTypeForm: (owner, isEdit) => {
|
||||
const tagLanguageKey = owner.getFormValue(prefix + 'tag_language');
|
||||
if (tagLanguageKey) {
|
||||
return <TableSelect
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
return <TableSelect
|
||||
id={prefix + 'mosaicoTemplate'}
|
||||
label={t('mosaicoTemplate')}
|
||||
withHeader
|
||||
dropdown
|
||||
dataUrl={`rest/mosaico-templates-by-tag-language-table/${tagLanguageKey}/` + getNamespaceIdFilterCookie()}
|
||||
columns={mosaicoTemplatesColumns}
|
||||
selectionLabelIndex={1}
|
||||
disabled={isEdit}/>
|
||||
}else{
|
||||
return <TableSelect
|
||||
id={prefix + 'mosaicoTemplate'}
|
||||
label={t('mosaicoTemplate')}
|
||||
withHeader
|
||||
|
@ -98,6 +110,7 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
columns={mosaicoTemplatesColumns}
|
||||
selectionLabelIndex={1}
|
||||
disabled={isEdit}/>
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ import {getTagLanguages} from '../helpers';
|
|||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
import PropTypes from 'prop-types';
|
||||
import {getNamespaceIdFilterCookie} from '../../lib/namespace';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import { id } from 'brace/worker/css';
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
|
@ -88,6 +91,11 @@ export default class List extends Component {
|
|||
}
|
||||
];
|
||||
|
||||
var mosaicoTemplatesTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/mosaico-templates-table" columns={columns} />;
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
mosaicoTemplatesTable = <Table ref={node => this.table = node} withHeader dataUrl={"rest/mosaico-templates-table/" + getNamespaceIdFilterCookie()} columns={columns}/>
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -103,7 +111,7 @@ export default class List extends Component {
|
|||
|
||||
<Title>{t('mosaicoTemplates')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/mosaico-templates-table" columns={columns} />
|
||||
{mosaicoTemplatesTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import mailtrainConfig from "mailtrainConfig";
|
|||
import {Icon} from "../lib/bootstrap-components";
|
||||
import {tableAddDeleteButton, tableRestActionDialogInit, tableRestActionDialogRender} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import {getNamespaceIdFilterCookie} from '../lib/namespace';
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
|
@ -59,6 +60,12 @@ export default class List extends Component {
|
|||
}
|
||||
});
|
||||
|
||||
var usersTable = <Table ref={node => this.table = node} withHeader dataUrl="rest/users-table" columns={columns} />
|
||||
|
||||
if(mailtrainConfig.namespaceFilterEnabled && getNamespaceIdFilterCookie()){
|
||||
usersTable = <Table ref={node => this.table = node} withHeader dataUrl={'rest/users-table/' + getNamespaceIdFilterCookie()} columns={columns} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{tableRestActionDialogRender(this)}
|
||||
|
@ -67,8 +74,7 @@ export default class List extends Component {
|
|||
</Toolbar>
|
||||
|
||||
<Title>{t('users')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl="rest/users-table" columns={columns} />
|
||||
{usersTable}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1024,5 +1024,9 @@
|
|||
"thePasswordMustContainAtLeastOne": "The password must contain at least one lowercase letter",
|
||||
"thePasswordMustContainAtLeastOne-1": "The password must contain at least one uppercase letter",
|
||||
"thePasswordMustContainAtLeastOneNumber": "The password must contain at least one number",
|
||||
"thePasswordMustContainAtLeastOneSpecial": "The password must contain at least one special character"
|
||||
"thePasswordMustContainAtLeastOneSpecial": "The password must contain at least one special character",
|
||||
"namespaceFilter": "Namespace filter",
|
||||
"filter": "Filter",
|
||||
"disallow": "Disallow",
|
||||
"selectAndReturn": "Select and return"
|
||||
}
|
|
@ -1024,5 +1024,9 @@
|
|||
"thePasswordMustContainAtLeastOne": "The password must contain at least one lowercase letter",
|
||||
"thePasswordMustContainAtLeastOne-1": "The password must contain at least one uppercase letter",
|
||||
"thePasswordMustContainAtLeastOneNumber": "The password must contain at least one number",
|
||||
"thePasswordMustContainAtLeastOneSpecial": "The password must contain at least one special character"
|
||||
"thePasswordMustContainAtLeastOneSpecial": "The password must contain at least one special character",
|
||||
"namespaceFilter": "Namespace filter",
|
||||
"filter": "Filter",
|
||||
"disallow": "Disallow",
|
||||
"selectAndReturn": "Select and return"
|
||||
}
|
|
@ -1103,5 +1103,9 @@
|
|||
"thePasswordMustContainAtLeastOne": "The password must contain at least one lowercase letter",
|
||||
"thePasswordMustContainAtLeastOne-1": "The password must contain at least one uppercase letter",
|
||||
"thePasswordMustContainAtLeastOneNumber": "The password must contain at least one number",
|
||||
"thePasswordMustContainAtLeastOneSpecial": "The password must contain at least one special character"
|
||||
"thePasswordMustContainAtLeastOneSpecial": "The password must contain at least one special character",
|
||||
"namespaceFilter": "Filtrado por espacio de nombres",
|
||||
"filter": "Filtro",
|
||||
"disallow": "Desactivar",
|
||||
"selectAndReturn": "Seleccionar y volver"
|
||||
}
|
|
@ -54,6 +54,9 @@ enabledLanguages:
|
|||
# Inject custom scripts in subscription/layout.mjml.hbs
|
||||
# customSubscriptionScripts: [/custom/hello-world.js]
|
||||
|
||||
#Enable to use Namespace Filter
|
||||
namespaceFilter:
|
||||
enabled: false
|
||||
|
||||
# Enable to use Redis session cache or disable if Redis is not installed
|
||||
redis:
|
||||
|
|
|
@ -23,6 +23,7 @@ async function getAnonymousConfig(context, appType) {
|
|||
sandboxUrlBaseDir: urls.getSandboxUrlBaseDir(),
|
||||
publicUrlBase: urls.getPublicUrlBase(),
|
||||
publicUrlBaseDir: urls.getPublicUrlBaseDir(),
|
||||
namespaceFilterEnabled: config.namespaceFilter.enabled,
|
||||
appType
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +50,8 @@ async function getAuthenticatedConfig(context) {
|
|||
verpEnabled: config.verp.enabled,
|
||||
reportsEnabled: config.reports.enabled,
|
||||
mapsApiKey: setts.mapsApiKey,
|
||||
builtinZoneMTAEnabled: config.builtinZoneMTA.enabled
|
||||
builtinZoneMTAEnabled: config.builtinZoneMTA.enabled,
|
||||
namespaceFilterEnabled: config.namespaceFilter.enabled
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ const contextHelpers = require('../lib/context-helpers');
|
|||
const {convertFileURLs} = require('../lib/campaign-content');
|
||||
const messageSender = require('../lib/message-sender');
|
||||
const lists = require('./lists');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const {EntityActivityType, CampaignActivityType} = require('../../shared/activity-log');
|
||||
const activityLog = require('../lib/activity-log');
|
||||
|
@ -67,26 +68,32 @@ function hash(entity, content) {
|
|||
return hasher.hash(filteredEntity);
|
||||
}
|
||||
|
||||
async function _listDTAjax(context, namespaceId, params) {
|
||||
async function _listDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'campaign', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => {
|
||||
builder = builder.from('campaigns')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace')
|
||||
.whereNull('campaigns.parent');
|
||||
if (namespaceId) {
|
||||
builder = builder.where('namespaces.id', namespaceId);
|
||||
}
|
||||
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace');
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('campaigns.namespace', allowedNamespaces[key]);
|
||||
}
|
||||
builder = builder.whereNull('campaigns.parent');
|
||||
return builder;
|
||||
},
|
||||
['campaigns.id', 'campaigns.name', 'campaigns.cid', 'campaigns.description', 'campaigns.type', 'campaigns.status', 'campaigns.scheduled', 'campaigns.source', 'campaigns.created', 'namespaces.name']
|
||||
);
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
return await _listDTAjax(context, undefined, params);
|
||||
async function listDTAjax(context, params, namespaceId) {
|
||||
return await _listDTAjax(context, namespaceId, params);
|
||||
}
|
||||
|
||||
async function listByNamespaceDTAjax(context, namespaceId, params) {
|
||||
|
@ -106,14 +113,25 @@ async function listChildrenDTAjax(context, campaignId, params) {
|
|||
}
|
||||
|
||||
|
||||
async function listWithContentDTAjax(context, params) {
|
||||
async function listWithContentDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'campaign', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => builder.from('campaigns')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace')
|
||||
.whereIn('campaigns.source', [CampaignSource.CUSTOM, CampaignSource.CUSTOM_FROM_TEMPLATE, CampaignSource.CUSTOM_FROM_CAMPAIGN]),
|
||||
builder => {
|
||||
builder = builder.from('campaigns')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'campaigns.namespace');
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('campaigns.namespace', allowedNamespaces[key]);
|
||||
}
|
||||
builder = builder.whereIn('campaigns.source', [CampaignSource.CUSTOM, CampaignSource.CUSTOM_FROM_TEMPLATE, CampaignSource.CUSTOM_FROM_CAMPAIGN]);
|
||||
return builder;
|
||||
},
|
||||
['campaigns.id', 'campaigns.name', 'campaigns.cid', 'campaigns.description', 'campaigns.type', 'campaigns.created', 'namespaces.name']
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ const mjml2html = require('mjml');
|
|||
|
||||
const lists = require('./lists');
|
||||
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||
const namespaces = require("./namespaces");
|
||||
|
||||
const formAllowedKeys = new Set([
|
||||
'name',
|
||||
|
@ -57,14 +58,28 @@ function hash(entity) {
|
|||
return hasher.hash(filterObject(entity, hashKeys));
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
async function listDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'customForm', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => builder
|
||||
.from('custom_forms')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'custom_forms.namespace'),
|
||||
builder => {
|
||||
builder = builder
|
||||
.from('custom_forms')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'custom_forms.namespace');
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('namespaces.id', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
['custom_forms.id', 'custom_forms.name', 'custom_forms.description', 'namespaces.name']
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ const segments = require('./segments');
|
|||
const imports = require('./imports');
|
||||
const entitySettings = require('../lib/entity-settings');
|
||||
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const {EntityActivityType} = require('../../shared/activity-log');
|
||||
const activityLog = require('../lib/activity-log');
|
||||
|
@ -26,8 +27,13 @@ function hash(entity) {
|
|||
}
|
||||
|
||||
|
||||
async function _listDTAjax(context, namespaceId, params) {
|
||||
async function _listDTAjax(context, namespaceFilter, params) {
|
||||
const campaignEntityType = entitySettings.getEntityType('campaign');
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
|
@ -37,9 +43,11 @@ async function _listDTAjax(context, namespaceId, params) {
|
|||
builder = builder
|
||||
.from('lists')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'lists.namespace');
|
||||
if (namespaceId) {
|
||||
builder = builder.where('lists.namespace', namespaceId);
|
||||
}
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('lists.namespace', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
['lists.id', 'lists.name', 'lists.cid', 'lists.subscribers', 'lists.description', 'namespaces.name',
|
||||
|
@ -59,11 +67,7 @@ async function _listDTAjax(context, namespaceId, params) {
|
|||
);
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
return await _listDTAjax(context, undefined, params);
|
||||
}
|
||||
|
||||
async function listByNamespaceDTAjax(context, namespaceId, params) {
|
||||
async function listDTAjax(context, namespaceId, params) {
|
||||
return await _listDTAjax(context, namespaceId, params);
|
||||
}
|
||||
|
||||
|
@ -274,7 +278,6 @@ async function remove(context, id) {
|
|||
module.exports.UnsubscriptionMode = UnsubscriptionMode;
|
||||
module.exports.hash = hash;
|
||||
module.exports.listDTAjax = listDTAjax;
|
||||
module.exports.listByNamespaceDTAjax = listByNamespaceDTAjax;
|
||||
module.exports.listWithSegmentByCampaignDTAjax = listWithSegmentByCampaignDTAjax;
|
||||
module.exports.getByIdTx = getByIdTx;
|
||||
module.exports.getById = getById;
|
||||
|
|
|
@ -10,6 +10,7 @@ const shares = require('./shares');
|
|||
const files = require('./files');
|
||||
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||
const { allTagLanguages } = require('../../shared/templates');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const allowedKeys = new Set(['name', 'description', 'type', 'tag_language', 'data', 'namespace']);
|
||||
|
||||
|
@ -27,24 +28,52 @@ async function getById(context, id) {
|
|||
});
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
async function listDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'mosaicoTemplate', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => builder.from('mosaico_templates').innerJoin('namespaces', 'namespaces.id', 'mosaico_templates.namespace'),
|
||||
builder => {
|
||||
builder = builder
|
||||
.from('mosaico_templates')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'mosaico_templates.namespace');
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('namespaces.id', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
[ 'mosaico_templates.id', 'mosaico_templates.name', 'mosaico_templates.description', 'mosaico_templates.type', 'mosaico_templates.tag_language', 'mosaico_templates.created', 'namespaces.name' ]
|
||||
);
|
||||
}
|
||||
|
||||
async function listByTagLanguageDTAjax(context, tagLanguage, params) {
|
||||
async function listByTagLanguageDTAjax(context, tagLanguage, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'mosaicoTemplate', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => builder.from('mosaico_templates')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'mosaico_templates.namespace')
|
||||
.where('mosaico_templates.tag_language', tagLanguage),
|
||||
builder => {
|
||||
builder = builder.from('mosaico_templates')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'mosaico_templates.namespace');
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('namespaces.id', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
builder = builder.where('mosaico_templates.tag_language', tagLanguage);
|
||||
return builder;
|
||||
},
|
||||
[ 'mosaico_templates.id', 'mosaico_templates.name', 'mosaico_templates.description', 'mosaico_templates.type', 'mosaico_templates.tag_language', 'mosaico_templates.created', 'namespaces.name' ]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ const dependencyHelpers = require('../lib/dependency-helpers');
|
|||
|
||||
const allowedKeys = new Set(['name', 'description', 'namespace']);
|
||||
|
||||
async function listTree(context) {
|
||||
|
||||
async function listTree(context, nsId, search) {
|
||||
enforce(!context.user.admin, 'listTree is not supposed to be called by assumed admin');
|
||||
|
||||
const entityType = entitySettings.getEntityType('namespace');
|
||||
|
@ -33,7 +34,7 @@ async function listTree(context) {
|
|||
'namespaces.id', 'namespaces.name', 'namespaces.description', 'namespaces.namespace',
|
||||
knex.raw(`GROUP_CONCAT(${entityType.permissionsTable + '.operation'} SEPARATOR \';\') as permissions`)
|
||||
]);
|
||||
|
||||
|
||||
const entries = {};
|
||||
|
||||
for (let row of rows) {
|
||||
|
@ -102,6 +103,30 @@ async function listTree(context) {
|
|||
delete entry.parent;
|
||||
}
|
||||
|
||||
if(nsId && !search){
|
||||
var root = [];
|
||||
|
||||
function process_node(node,topNamespace){
|
||||
var branch = false;
|
||||
if(node){
|
||||
if(node.key == topNamespace){
|
||||
branch = true;
|
||||
return node;
|
||||
}
|
||||
if(node.children && !branch){
|
||||
for(const key in node.children){
|
||||
const n = process_node(node.children[key], topNamespace);
|
||||
if(n){
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
root.push(process_node(roots[0], nsId));
|
||||
return root;
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
|
@ -241,6 +266,35 @@ async function remove(context, id) {
|
|||
});
|
||||
}
|
||||
|
||||
async function getAllowedNamespaces(context, topNamespace){
|
||||
|
||||
const tree = await listTree(context, null, true);
|
||||
var allowedNamespaces = [];
|
||||
|
||||
function process_node(node, namespaces, branch, topNamespace){
|
||||
if(node){
|
||||
if(branch){
|
||||
namespaces.push(node.key);
|
||||
}
|
||||
if(node.key == topNamespace){
|
||||
branch = true;
|
||||
namespaces.push(node.key);
|
||||
}
|
||||
if(node.children){
|
||||
for(const key in node.children){
|
||||
process_node(node.children[key], namespaces, branch, topNamespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(tree && topNamespace){
|
||||
process_node(tree[0], allowedNamespaces, false, topNamespace);
|
||||
allowedNamespaces.sort();
|
||||
}
|
||||
|
||||
return allowedNamespaces;
|
||||
}
|
||||
|
||||
module.exports.hash = hash;
|
||||
module.exports.listTree = listTree;
|
||||
module.exports.getById = getById;
|
||||
|
@ -249,3 +303,4 @@ module.exports.create = create;
|
|||
module.exports.createTx = createTx;
|
||||
module.exports.updateWithConsistencyCheck = updateWithConsistencyCheck;
|
||||
module.exports.remove = remove;
|
||||
module.exports.getAllowedNamespaces = getAllowedNamespaces;
|
|
@ -9,6 +9,7 @@ const namespaceHelpers = require('../lib/namespace-helpers');
|
|||
const shares = require('./shares');
|
||||
const reports = require('./reports');
|
||||
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const allowedKeys = new Set(['name', 'description', 'mime_type', 'user_fields', 'js', 'hbs', 'namespace']);
|
||||
|
||||
|
@ -25,12 +26,26 @@ async function getById(context, id) {
|
|||
});
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
async function listDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'reportTemplate', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => builder.from('report_templates').innerJoin('namespaces', 'namespaces.id', 'report_templates.namespace'),
|
||||
builder => {
|
||||
builder = builder.from('report_templates')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'report_templates.namespace');
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('namespaces.id', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
[ 'report_templates.id', 'report_templates.name', 'report_templates.description', 'report_templates.created', 'namespaces.name' ]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ const contextHelpers = require('../lib/context-helpers');
|
|||
const {LinkId} = require('./links');
|
||||
const subscriptions = require('./subscriptions');
|
||||
const {Readable} = require('stream');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const ReportState = require('../../shared/reports').ReportState;
|
||||
|
||||
|
@ -45,7 +46,12 @@ async function getByIdWithTemplate(context, id, withPermissions = true) {
|
|||
});
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
async function listDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[
|
||||
|
@ -53,9 +59,17 @@ async function listDTAjax(context, params) {
|
|||
{ entityTypeId: 'reportTemplate', requiredOperations: ['view'] }
|
||||
],
|
||||
params,
|
||||
builder => builder.from('reports')
|
||||
.innerJoin('report_templates', 'reports.report_template', 'report_templates.id')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'reports.namespace'),
|
||||
builder => {
|
||||
builder = builder.from('reports')
|
||||
.innerJoin('report_templates', 'reports.report_template', 'report_templates.id')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'reports.namespace');
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('namespaces.id', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
[
|
||||
'reports.id', 'reports.name', 'report_templates.name', 'reports.description',
|
||||
'reports.last_run', 'namespaces.name', 'reports.state', 'report_templates.mime_type'
|
||||
|
|
|
@ -13,6 +13,7 @@ const contextHelpers = require('../lib/context-helpers');
|
|||
const mailers = require('../lib/mailers');
|
||||
const senders = require('../lib/senders');
|
||||
const dependencyHelpers = require('../lib/dependency-helpers');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const allowedKeys = new Set(['name', 'description', 'from_email', 'from_email_overridable', 'from_name', 'from_name_overridable', 'reply_to', 'reply_to_overridable', 'x_mailer', 'verp_hostname', 'verp_disable_sender_header', 'mailer_type', 'mailer_settings', 'namespace']);
|
||||
|
||||
|
@ -22,7 +23,14 @@ function hash(entity) {
|
|||
return hasher.hash(filterObject(entity, allowedKeys));
|
||||
}
|
||||
|
||||
async function _listDTAjax(context, namespaceId, params) {
|
||||
async function _listDTAjax(context, namespaceFilter, params) {
|
||||
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'sendConfiguration', requiredOperations: ['viewPublic'] }],
|
||||
|
@ -31,8 +39,10 @@ async function _listDTAjax(context, namespaceId, params) {
|
|||
builder = builder
|
||||
.from('send_configurations')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'send_configurations.namespace');
|
||||
if (namespaceId) {
|
||||
builder = builder.where('send_configurations.namespace', namespaceId);
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('send_configurations.namespace', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
|
@ -40,8 +50,8 @@ async function _listDTAjax(context, namespaceId, params) {
|
|||
);
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
return await _listDTAjax(context, undefined, params);
|
||||
async function listDTAjax(context, namespaceId, params) {
|
||||
return await _listDTAjax(context, namespaceId, params);
|
||||
}
|
||||
|
||||
async function listByNamespaceDTAjax(context, namespaceId, params) {
|
||||
|
|
|
@ -12,6 +12,7 @@ const dependencyHelpers = require('../lib/dependency-helpers');
|
|||
const {convertFileURLs} = require('../lib/campaign-content');
|
||||
const { allTagLanguages } = require('../../shared/templates');
|
||||
const messageSender = require('../lib/message-sender');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const allowedKeys = new Set(['name', 'description', 'type', 'tag_language', 'data', 'html', 'text', 'namespace']);
|
||||
|
||||
|
@ -37,15 +38,23 @@ async function getById(context, id, withPermissions = true) {
|
|||
});
|
||||
}
|
||||
|
||||
async function _listDTAjax(context, namespaceId, params) {
|
||||
async function _listDTAjax(context, namespaceFilter, params) {
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'template', requiredOperations: ['view'] }],
|
||||
params,
|
||||
builder => {
|
||||
builder = builder.from('templates').innerJoin('namespaces', 'namespaces.id', 'templates.namespace');
|
||||
if (namespaceId) {
|
||||
builder = builder.where('namespaces.id', namespaceId);
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('namespaces.id', allowedNamespaces[key]);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
},
|
||||
|
@ -53,11 +62,7 @@ async function _listDTAjax(context, namespaceId, params) {
|
|||
);
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
return await _listDTAjax(context, undefined, params);
|
||||
}
|
||||
|
||||
async function listByNamespaceDTAjax(context, namespaceId, params) {
|
||||
async function listDTAjax(context, namespaceId, params) {
|
||||
return await _listDTAjax(context, namespaceId, params);
|
||||
}
|
||||
|
||||
|
@ -177,7 +182,6 @@ module.exports.hash = hash;
|
|||
module.exports.getByIdTx = getByIdTx;
|
||||
module.exports.getById = getById;
|
||||
module.exports.listDTAjax = listDTAjax;
|
||||
module.exports.listByNamespaceDTAjax = listByNamespaceDTAjax;
|
||||
module.exports.create = create;
|
||||
module.exports.updateWithConsistencyCheck = updateWithConsistencyCheck;
|
||||
module.exports.remove = remove;
|
||||
|
|
|
@ -14,6 +14,7 @@ const {getTrustedUrl} = require('../lib/urls');
|
|||
const { tUI } = require('../lib/translate');
|
||||
const messageSender = require('../lib/message-sender');
|
||||
const {getSystemSendConfigurationId} = require('../../shared/send-configurations');
|
||||
const namespaces = require('./namespaces');
|
||||
|
||||
const bluebird = require('bluebird');
|
||||
|
||||
|
@ -108,17 +109,35 @@ async function serverValidate(context, data, isOwnAccount) {
|
|||
return result;
|
||||
}
|
||||
|
||||
async function listDTAjax(context, params) {
|
||||
async function listDTAjax(context, namespaceFilter, params) {
|
||||
|
||||
var allowedNamespaces = [];
|
||||
|
||||
if(namespaceFilter){
|
||||
allowedNamespaces = await namespaces.getAllowedNamespaces(context, namespaceFilter);
|
||||
}
|
||||
|
||||
return await dtHelpers.ajaxListWithPermissions(
|
||||
context,
|
||||
[{ entityTypeId: 'namespace', requiredOperations: ['manageUsers'] }],
|
||||
params,
|
||||
builder => builder
|
||||
.from('users')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'users.namespace')
|
||||
.innerJoin('generated_role_names', 'generated_role_names.role', 'users.role')
|
||||
.where('generated_role_names.entity_type', 'global'),
|
||||
[ 'users.id', 'users.username', 'users.name', 'namespaces.name', 'generated_role_names.name' ]
|
||||
builder => {
|
||||
builder = builder
|
||||
.from('users')
|
||||
.innerJoin('namespaces', 'namespaces.id', 'users.namespace')
|
||||
.innerJoin('generated_role_names', 'generated_role_names.role', 'users.role')
|
||||
|
||||
if (namespaceFilter) {
|
||||
for(const key in allowedNamespaces){
|
||||
builder = builder.orWhere('generated_role_names.entity_type', 'global').andWhere('users.namespace', allowedNamespaces[key]);
|
||||
}
|
||||
}else{
|
||||
builder = builder.where('generated_role_names.entity_type', 'global');
|
||||
}
|
||||
|
||||
return builder;
|
||||
},
|
||||
[ 'users.id', 'users.username', 'users.name', 'namespaces.name', 'generated_role_names.name' ]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,20 @@ const campaigns = require('../../models/campaigns');
|
|||
const router = require('../../lib/router-async').create();
|
||||
const {castToInteger} = require('../../lib/helpers');
|
||||
|
||||
|
||||
router.postAsync('/campaigns-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await campaigns.listDTAjax(req.context, req.body));
|
||||
return res.json(await campaigns.listDTAjax(req.context, req.body, null));
|
||||
});
|
||||
|
||||
router.postAsync('/campaigns-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await campaigns.listDTAjax(req.context, req.body, castToInteger(req.params.namespaceId)));
|
||||
});
|
||||
|
||||
router.postAsync('/campaigns-with-content-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await campaigns.listWithContentDTAjax(req.context, req.body));
|
||||
return res.json(await campaigns.listWithContentDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/campaigns-with-content-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await campaigns.listWithContentDTAjax(req.context, req.params.namespaceId, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/campaigns-others-by-list-table/:campaignId/:listIds', passport.loggedIn, async (req, res) => {
|
||||
|
|
|
@ -13,7 +13,11 @@ const {castToInteger} = require('../../lib/helpers');
|
|||
|
||||
|
||||
router.postAsync('/forms-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await forms.listDTAjax(req.context, req.body));
|
||||
return res.json(await forms.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/forms-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await forms.listDTAjax(req.context, req.params.namespaceId, req.body));
|
||||
});
|
||||
|
||||
router.getAsync('/forms/:formId', passport.loggedIn, async (req, res) => {
|
||||
|
|
|
@ -8,11 +8,11 @@ const {castToInteger} = require('../../lib/helpers');
|
|||
|
||||
|
||||
router.postAsync('/lists-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await lists.listDTAjax(req.context, req.body));
|
||||
return res.json(await lists.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/lists-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await lists.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
router.postAsync('/lists-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await lists.listDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/lists-with-segment-by-campaign-table/:campaignId', passport.loggedIn, async (req, res) => {
|
||||
|
|
|
@ -30,11 +30,19 @@ router.deleteAsync('/mosaico-templates/:mosaicoTemplateId', passport.loggedIn, p
|
|||
});
|
||||
|
||||
router.postAsync('/mosaico-templates-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await mosaicoTemplates.listDTAjax(req.context, req.body));
|
||||
return res.json(await mosaicoTemplates.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/mosaico-templates-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await mosaicoTemplates.listDTAjax(req.context, req.params.namespaceId, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/mosaico-templates-by-tag-language-table/:tagLanguage', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await mosaicoTemplates.listByTagLanguageDTAjax(req.context, req.params.tagLanguage, req.body));
|
||||
return res.json(await mosaicoTemplates.listByTagLanguageDTAjax(req.context, req.params.tagLanguage, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/mosaico-templates-by-tag-language-table/:tagLanguage/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await mosaicoTemplates.listByTagLanguageDTAjax(req.context, req.params.tagLanguage, req.params.namespaceId, req.body));
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -32,9 +32,16 @@ router.deleteAsync('/namespaces/:nsId', passport.loggedIn, passport.csrfProtecti
|
|||
return res.json();
|
||||
});
|
||||
|
||||
router.getAsync('/namespaces-tree/:nsId', passport.loggedIn, async (req, res) => {
|
||||
|
||||
const tree = await namespaces.listTree(req.context, req.params.nsId, false);
|
||||
|
||||
return res.json(tree);
|
||||
});
|
||||
|
||||
router.getAsync('/namespaces-tree', passport.loggedIn, async (req, res) => {
|
||||
|
||||
const tree = await namespaces.listTree(req.context);
|
||||
const tree = await namespaces.listTree(req.context, null, false);
|
||||
|
||||
return res.json(tree);
|
||||
});
|
||||
|
|
|
@ -31,7 +31,11 @@ router.deleteAsync('/report-templates/:reportTemplateId', passport.loggedIn, pas
|
|||
});
|
||||
|
||||
router.postAsync('/report-templates-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await reportTemplates.listDTAjax(req.context, req.body));
|
||||
return res.json(await reportTemplates.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/report-templates-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await reportTemplates.listDTAjax(req.context, req.params.namespaceId, req.body));
|
||||
});
|
||||
|
||||
router.getAsync('/report-template-user-fields/:reportTemplateId', passport.loggedIn, async (req, res) => {
|
||||
|
|
|
@ -35,7 +35,11 @@ router.deleteAsync('/reports/:reportId', passport.loggedIn, passport.csrfProtect
|
|||
});
|
||||
|
||||
router.postAsync('/reports-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await reports.listDTAjax(req.context, req.body));
|
||||
return res.json(await reports.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/reports-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await reports.listDTAjax(req.context, req.params.namespaceId, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/report-start/:id', passport.loggedIn, passport.csrfProtection, async (req, res) => {
|
||||
|
|
|
@ -37,11 +37,11 @@ router.deleteAsync('/send-configurations/:sendConfigurationId', passport.loggedI
|
|||
});
|
||||
|
||||
router.postAsync('/send-configurations-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await sendConfigurations.listDTAjax(req.context, req.body));
|
||||
return res.json(await sendConfigurations.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/send-configurations-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await sendConfigurations.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
router.postAsync('/send-configurations-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await sendConfigurations.listDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/send-configurations-with-send-permission-table', passport.loggedIn, async (req, res) => {
|
||||
|
|
|
@ -31,11 +31,11 @@ router.deleteAsync('/templates/:templateId', passport.loggedIn, passport.csrfPro
|
|||
});
|
||||
|
||||
router.postAsync('/templates-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await templates.listDTAjax(req.context, req.body));
|
||||
return res.json(await templates.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/templates-by-namespace-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await templates.listByNamespaceDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
router.postAsync('/templates-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await templates.listDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
});
|
||||
|
||||
module.exports = router;
|
|
@ -35,7 +35,11 @@ router.postAsync('/users-validate', passport.loggedIn, async (req, res) => {
|
|||
});
|
||||
|
||||
router.postAsync('/users-table', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await users.listDTAjax(req.context, req.body));
|
||||
return res.json(await users.listDTAjax(req.context, null, req.body));
|
||||
});
|
||||
|
||||
router.postAsync('/users-table/:namespaceId', passport.loggedIn, async (req, res) => {
|
||||
return res.json(await users.listDTAjax(req.context, castToInteger(req.params.namespaceId), req.body));
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue