<commit_before>/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2005-2015 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
(function() {

"use strict";

var ui = angular.module('axelor.ui');

ui.factory('MessageService', ['$q', '$timeout', 'DataSource', 'TagService', function($q, $timeout, DataSource, TagService) {

	var dsFlags = DataSource.create('com.axelor.mail.db.MailFlags');
	var dsMessage = DataSource.create('com.axelor.mail.db.MailMessage');

	var pollResult = {};

	TagService.listen(function (data) {
		pollResult = data.mail || {};
	});

	/**
	 * Get the followers of the given record.
	 *
	 */
	function getFollowers(relatedModel, relatedId) {
		var ds = DataSource.create(relatedModel);
		return ds.followers(relatedId);
	}

	/**
	 * Get messages with the given options.
	 *
	 * The options can have following values:
	 *
	 * - relatedId = related record id
	 * - relatedModel = related model
	 * - folder = only from given folder
	 *
	 * @param {Object} options - search options
	 * @return {Promise}
	 */
	function getMessages(options) {
		var opts = _.extend({}, options);
		return dsMessage.messages(opts);
	}

	/**
	 * Get replies of the given message.
	 *
	 */
	function getReplies(parent) {
		var deferred = $q.defer();
		var opts = {
			parent: parent.id
		};

		var promise = dsMessage.messages(opts)
		.error(deferred.reject)
		.success(function (res) {
			var records = res.data || [];
			deferred.resolve(records);
		});

		return deferred.promise;
	}

	/**
	 * Toggle flags on the given message.
	 *
	 * Flag state can be:
	 *
	 * 1 = mark read
	 * 2 = mark starred
	 * 3 = mark archived
	 *
	 * Negative value unmarks the flag.
	 *
	 * @param {object|array} message - the message
	 * @param {number} flagState - flag state
	 */
	function flagMessage(message, flagState) {
		var messages = _.isArray(message) ? message : [message];
		var ref = {};
		var all = _.map(messages, function (message) {
			var flags = _.extend({}, message.$flags);
			if (flagState === 1) flags.isRead = true;
			if (flagState === -1) flags.isRead = false;
			if (flagState === 2) flags.isStarred = true;
			if (flagState === -2) flags.isStarred = false;
			if (flagState === 3) flags.isArchived = true;
			if (flagState === -3) flags.isArchived = false;

			flags.message = _.pick(message, 'id');
			flags.user = {
				id: axelor.config['user.id']
			};

			ref[""+message.id] = message;

			return flags;
		});

		var promise = dsFlags.saveAll(all);
		promise.success(function (records) {
			_.each(records, function (rec) {
				var msg = ref[""+rec.message.id];
				if (msg) {
					msg.$flags = _.pick(rec, ['id', 'version', 'isStarred', 'isRead', 'isArchived']);
				}
			});
			// force unread check
			if (flagState === 1 || flagState == -1) {
				TagService.find();
			}
		});

		return promise;
	}

	function removeMessage(message) {
		var promise = dsMessage.remove(message);
		promise.then(function () {
			TagService.find(); // force unread check
		});
		return promise;
	}

	return {
		getFollowers: getFollowers,
		getMessages: getMessages,
		getReplies: getReplies,
		flagMessage: flagMessage,
		removeMessage: removeMessage,
		unreadCount: function () {
			return pollResult.unread;
		}
	};
}]);

ui.directive('uiMailMessage', function () {
	return {
		require: '^uiMailMessages',
		replace: true,
		link: function (scope, element, attrs) {

			var message = scope.message;
			var body = message.body || "{}";
			if (body.indexOf("{") === 0) {
				body = angular.fromJson(body);
				body.tags = _.map(body.tags, function (tag) {
					if (tag.style) {
						tag.css = 'label-' + tag.style;
					}
					return tag;
				});
				scope.body = body;
			} else {
				scope.body = null;
			}

			function format(value) {
				if (!value) {
					return value;
				}
				if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?$/.test(value)) {
					return moment(value).format("DD/MM/YYYY HH:mm");
				}
				if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
					return moment(value).format("DD/MM/YYYY");
				}
				return value;
			}

			if (body && body.tracks) {
				_.each(body.tracks, function (item) {
					item.displayValue = format(item.value);
					if (item.oldValue !== undefined) {
						item.displayValue += " &raquo; " + format(item.oldValue);
					}
				});
			}

			message.$title = (body||{}).title || message.subject;

			scope.showFull = !message.summary;
			scope.onShowFull = function () {
				scope.showFull = true;
			};

			setTimeout(function () {<commit_msg>Fix the change tracking value display order<commit_after>/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2005-2015 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
(function() {

"use strict";

var ui = angular.module('axelor.ui');

ui.factory('MessageService', ['$q', '$timeout', 'DataSource', 'TagService', function($q, $timeout, DataSource, TagService) {

	var dsFlags = DataSource.create('com.axelor.mail.db.MailFlags');
	var dsMessage = DataSource.create('com.axelor.mail.db.MailMessage');

	var pollResult = {};

	TagService.listen(function (data) {
		pollResult = data.mail || {};
	});

	/**
	 * Get the followers of the given record.
	 *
	 */
	function getFollowers(relatedModel, relatedId) {
		var ds = DataSource.create(relatedModel);
		return ds.followers(relatedId);
	}

	/**
	 * Get messages with the given options.
	 *
	 * The options can have following values:
	 *
	 * - relatedId = related record id
	 * - relatedModel = related model
	 * - folder = only from given folder
	 *
	 * @param {Object} options - search options
	 * @return {Promise}
	 */
	function getMessages(options) {
		var opts = _.extend({}, options);
		return dsMessage.messages(opts);
	}

	/**
	 * Get replies of the given message.
	 *
	 */
	function getReplies(parent) {
		var deferred = $q.defer();
		var opts = {
			parent: parent.id
		};

		var promise = dsMessage.messages(opts)
		.error(deferred.reject)
		.success(function (res) {
			var records = res.data || [];
			deferred.resolve(records);
		});

		return deferred.promise;
	}

	/**
	 * Toggle flags on the given message.
	 *
	 * Flag state can be:
	 *
	 * 1 = mark read
	 * 2 = mark starred
	 * 3 = mark archived
	 *
	 * Negative value unmarks the flag.
	 *
	 * @param {object|array} message - the message
	 * @param {number} flagState - flag state
	 */
	function flagMessage(message, flagState) {
		var messages = _.isArray(message) ? message : [message];
		var ref = {};
		var all = _.map(messages, function (message) {
			var flags = _.extend({}, message.$flags);
			if (flagState === 1) flags.isRead = true;
			if (flagState === -1) flags.isRead = false;
			if (flagState === 2) flags.isStarred = true;
			if (flagState === -2) flags.isStarred = false;
			if (flagState === 3) flags.isArchived = true;
			if (flagState === -3) flags.isArchived = false;

			flags.message = _.pick(message, 'id');
			flags.user = {
				id: axelor.config['user.id']
			};

			ref[""+message.id] = message;

			return flags;
		});

		var promise = dsFlags.saveAll(all);
		promise.success(function (records) {
			_.each(records, function (rec) {
				var msg = ref[""+rec.message.id];
				if (msg) {
					msg.$flags = _.pick(rec, ['id', 'version', 'isStarred', 'isRead', 'isArchived']);
				}
			});
			// force unread check
			if (flagState === 1 || flagState == -1) {
				TagService.find();
			}
		});

		return promise;
	}

	function removeMessage(message) {
		var promise = dsMessage.remove(message);
		promise.then(function () {
			TagService.find(); // force unread check
		});
		return promise;
	}

	return {
		getFollowers: getFollowers,
		getMessages: getMessages,
		getReplies: getReplies,
		flagMessage: flagMessage,
		removeMessage: removeMessage,
		unreadCount: function () {
			return pollResult.unread;
		}
	};
}]);

ui.directive('uiMailMessage', function () {
	return {
		require: '^uiMailMessages',
		replace: true,
		link: function (scope, element, attrs) {

			var message = scope.message;
			var body = message.body || "{}";
			if (body.indexOf("{") === 0) {
				body = angular.fromJson(body);
				body.tags = _.map(body.tags, function (tag) {
					if (tag.style) {
						tag.css = 'label-' + tag.style;
					}
					return tag;
				});
				scope.body = body;
			} else {
				scope.body = null;
			}

			function format(value) {
				if (!value) {
					return value;
				}
				if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?$/.test(value)) {
					return moment(value).format("DD/MM/YYYY HH:mm");
				}
				if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
					return moment(value).format("DD/MM/YYYY");
				}
				return value;
			}

			if (body && body.tracks) {
				_.each(body.tracks, function (item) {
					item.displayValue = format(item.value);
					if (item.oldValue !== undefined) {
						item.displayValue = format(item.oldValue) + " &raquo; " + item.displayValue;
					}
				});
			}

			message.$title = (body||{}).title || message.subject;

			scope.showFull = !message.summary;
			scope.onShowFull = function () {
				scope.showFull = true;
			};

			setTimeout(function () {
{'fraction_non_alphanumeric': 0.15560349053828806, 'fraction_numerical': 0.005882929698990097, 'mean_word_length': 3.07673860911271, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6880573', 'n_tokens_mistral': 3873, 'n_tokens_neox': 3280, 'n_words': 885}