2021-05-14 17:17:06 +03:00

380 lines
14 KiB
TypeScript

import { Injectable } from '@angular/core';
import { assign, cloneDeep } from 'lodash-es';
import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
import { filters as filtersData, folders as foldersData, labels as labelsData, mails as mailsData, settings as settingsData } from 'app/mock-api/apps/mailbox/data';
@Injectable({
providedIn: 'root'
})
export class MailboxMockApi
{
private _filters: any[] = filtersData;
private _folders: any[] = foldersData;
private _mails: any[] = mailsData;
private _labels: any[] = labelsData;
private _settings: any = settingsData;
/**
* Constructor
*/
constructor(private _fuseMockApiService: FuseMockApiService)
{
// Register Mock API handlers
this.registerHandlers();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Register Mock API handlers
*/
registerHandlers(): void
{
// -----------------------------------------------------------------------------------------------------
// @ Settings - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/mailbox/settings')
.reply(() => [200, cloneDeep(this._settings)]);
// -----------------------------------------------------------------------------------------------------
// @ Settings - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/mailbox/settings')
.reply(({request}) => {
// Get the settings
const settings = cloneDeep(request.body.settings);
// Update the settings
this._settings = assign({}, this._settings, settings);
// Return the response
return [200, cloneDeep(this._settings)];
});
// -----------------------------------------------------------------------------------------------------
// @ Folders - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/mailbox/folders')
.reply(() => {
let count = 0;
// Iterate through the folders
this._folders.forEach((folder) => {
// Get the mails of this folder
const mails = this._mails.filter(mail => mail.folder === folder.id);
// If we are counting the 'sent' or the 'trash' folder...
if ( folder.slug === 'sent' || folder.slug === 'trash' )
{
// Always set the count to 0
count = 0;
}
// If we are counting the 'drafts' or the 'spam' folder...
else if ( folder.slug === 'drafts' || folder.slug === 'trash' || folder.slug === 'spam' )
{
// Set the count to the count of all mails
count = mails.length;
}
// Otherwise ('inbox')...
else
{
// Go through the mails and count the unread ones
mails.forEach((mail) => {
if ( mail.unread )
{
count++;
}
});
}
// Append the count to the folder mock-api
folder.count = count;
// Reset the count
count = 0;
});
// Return the response
return [200, cloneDeep(this._folders)];
});
// -----------------------------------------------------------------------------------------------------
// @ Filters - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/mailbox/filters')
.reply(() => [200, cloneDeep(this._filters)]);
// -----------------------------------------------------------------------------------------------------
// @ Labels - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/mailbox/labels')
.reply(() => [200, cloneDeep(this._labels)]);
// -----------------------------------------------------------------------------------------------------
// @ Labels - POST
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPost('api/apps/mailbox/label')
.reply(({request}) => {
// Get the label
const label = cloneDeep(request.body.label);
// Generate an id
label.id = FuseMockApiUtils.guid();
// Generate a slug
label.slug = label.title.toLowerCase()
.replace(/ /g, '-')
.replace(/[-]+/g, '-')
.replace(/[^\w-]+/g, '');
// Check if the slug is being used and update it if necessary
const originalSlug = label.slug;
let sameSlug;
let slugSuffix = 1;
do
{
sameSlug = this._labels.filter(item => item.slug === label.slug);
if ( sameSlug.length > 0 )
{
label.slug = originalSlug + '-' + slugSuffix;
slugSuffix++;
}
}
while ( sameSlug.length > 0 );
// Add the label
this._labels.push(label);
// Return the response
return [200, label];
});
// -----------------------------------------------------------------------------------------------------
// @ Labels - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/mailbox/label')
.reply(({request}) => {
// Get the id and label
const id = request.body.id;
const label = cloneDeep(request.body.label);
// Prepare the updated label
let updatedLabel = null;
// Find the label and update it
this._labels.forEach((item, index, labels) => {
if ( item.id === id )
{
// Update the slug
label.slug = label.title.toLowerCase()
.replace(/ /g, '-')
.replace(/[-]+/g, '-')
.replace(/[^\w-]+/g, '');
// Update the label
labels[index] = assign({}, labels[index], label);
// Store the updated label
updatedLabel = labels[index];
}
});
// Return the response
return [200, updatedLabel];
});
// -----------------------------------------------------------------------------------------------------
// @ Labels - DELETE
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onDelete('api/apps/mailbox/label')
.reply(({request}) => {
// Get the id
const id = request.params.get('id');
// Find the label and delete it
const index = this._labels.findIndex(item => item.id === id);
this._labels.splice(index, 1);
// Get all the mails that have the label
const mailsWithLabel = this._mails.filter(mail => mail.labels.indexOf(id) > -1);
// Iterate through them and remove the label
mailsWithLabel.forEach((mail) => {
mail.labels.splice(mail.labels.indexOf(id), 1);
});
// Return the response
return [200, true];
});
// -----------------------------------------------------------------------------------------------------
// @ Mails - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/mailbox/mails', 625)
.reply(({request}) => {
// First, decide if mails are requested by folder, filter or label
const byFolder = request.params.get('folder');
const byFilter = request.params.get('filter');
const byLabel = request.params.get('label');
// Clone the mails mock-api to prevent accidental mock-api updates
let mails: any[] | null = cloneDeep(this._mails);
// Filter the mails depending on the requested by type
mails = mails.filter((mail) => {
if ( byFolder )
{
return mail.folder === this._folders.find(folder => folder.slug === byFolder).id;
}
if ( byFilter )
{
return mail[byFilter] === true;
}
if ( byLabel )
{
return mail.labels.includes(this._labels.find(label => label.slug === byLabel).id);
}
});
// Sort by date - descending
mails.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
// Figure out the cc and bcc counts
mails.forEach((mail) => {
mail.ccCount = mail.cc ? mail.cc.length : 0;
mail.bccCount = mail.bcc ? mail.bcc.length : 0;
});
// Paginate - Start
const mailsLength = mails.length;
const resultsPerPage = 10;
// Get the requested page number
const page = parseInt(request.params.get('page') ?? '1', 10);
// Calculate pagination details
const begin = (page - 1) * resultsPerPage;
const end = Math.min((resultsPerPage * page), mailsLength);
const lastPage = Math.max(Math.ceil(mailsLength / resultsPerPage), 1);
// Prepare the pagination object
let pagination = {};
// If the requested page number is bigger than
// the last possible page number, return null for
// mails but also send the last possible page so
// the app can navigate to there
if ( page > lastPage )
{
mails = null;
pagination = {
lastPage
};
}
else
{
// Paginate the results by 10
mails = mails.slice(begin, end);
// Prepare the pagination mock-api
pagination = {
totalResults : mailsLength,
resultsPerPage: resultsPerPage,
currentPage : page,
lastPage : lastPage,
startIndex : begin,
endIndex : end - 1
};
}
// Return the response
return [
200,
{
mails,
pagination
}
];
});
// -----------------------------------------------------------------------------------------------------
// @ Mail - GET
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onGet('api/apps/mailbox/mail')
.reply(({request}) => {
// Get the id from the params
const id = request.params.get('id');
// Clone the mails mock-api to prevent accidental mock-api updates
const mails = cloneDeep(this._mails);
// Find the mail
const mail = mails.find(item => item.id === id);
return [
200,
mail
];
});
// -----------------------------------------------------------------------------------------------------
// @ Mail - PATCH
// -----------------------------------------------------------------------------------------------------
this._fuseMockApiService
.onPatch('api/apps/mailbox/mail')
.reply(({request}) => {
// Get the id and mail
const id = request.body.id;
const mail = cloneDeep(request.body.mail);
// Prepare the updated mail
let updatedMail = null;
// Find the mail and update it
this._mails.forEach((item, index, mails) => {
if ( item.id === id )
{
// Update the mail
mails[index] = assign({}, mails[index], mail);
// Store the updated mail
updatedMail = mails[index];
}
});
// Return the response
return [200, updatedMail];
});
}
}