ucan-ext-js-kitchen-sink
Version:
my-ext-gen-app description for Ext JS app MyExtGenApp
387 lines (369 loc) • 14 kB
JavaScript
Ext.define('UCAN.comment.src.comment', {
extend: 'Ext.Container',
xtype: 'comment',
viewModel: {},
config: {
comments: null,
currentUser: null,
translator: null,
froalaConfig: {
attribution: false,
charCounterCount: false,
toolbarButtons: {
'moreText': {
'buttons': ['bold', 'italic', 'underline', 'subscript', 'superscript', 'clearFormatting'],
'buttonsVisible': 6
},
'moreParagraph': {
'buttons': ['outdent', 'indent'],
'buttonsVisible': 2
},
'moreRich': {
'buttons': ['insertTable', 'specialCharacters', 'insert', 'emoticons'],
'buttonsVisible': 4
},
'moreMisc': {
'buttons': ['undo', 'redo', 'fullscreen', 'spellChecker', 'selectAll', 'help'],
'align': 'right',
'buttonsVisible': 7
}
},
pluginsEnabled: ['image', 'link', 'emoticons', 'fullscreen', 'table']
},
contextId: null,
contextEntityId: null,
disableEdit: true,
type: null
},
twoWayBindable: {
comments: true,
currentUser: true,
translator: true,
froalaConfig: true
},
scrollable: true,
defaultListenerScope: this,
items: [
{
xtype: 'toolbar',
cls: 'ucan-comment-toolbar',
docked: 'bottom',
items: [
{
xtype: 'button',
enableToggle: true,
iconCls: 'x-fa fa-comment',
cls: 'js-ucan-comment-button-add',
handler: 'onAddNewComment'
}
]
},
{
xtype: 'toolbar',
docked: 'top',
cls: 'ucan-comment-toolbar',
items: [
{
xtype: 'label',
cls: 'js-ucan-comment-label-filter ucan-comment-label-filter'
},
{
xtype: 'segmentedbutton',
cls: 'js-ucan-comment-segmentedbutton-filter ucan-comment-segmentedbutton-filter',
allowMultiple: false,
allowToggle: true,
value: 'DEFAULT',
listeners: {
toggle: 'onChangeCommentFilter'
},
items: [
{
iconCls: 'x-fa fa-comment',
cls: 'js-ucan-comment-button-filter-default ucan-comment-button-filter-default',
handler: 'onToggleDefaultFilter',
value: 'DEFAULT'
},
{
iconCls: 'x-fa fa-star-half-alt',
cls: 'js-ucan-comment-button-filter-review ucan-comment-button-filter-review',
value: 'REVIEW',
handler: 'onToggleReviewFilter'
},
{
iconCls: 'x-fa fa-chart-line',
cls: 'js-ucan-comment-button-filter-statistic ucan-comment-button-filter-statistic',
enableToggle: true,
value: 'STATISTIC',
handler: 'onToggleStatisticFilter'
}
]
}
]
},
{
xtype: 'tree',
infinite: false,
cls: 'js-ucan-comment-tree ucan-comment-tree',
selectable: false,
hideHeaders: true,
expanderFirst: true,
variableHeights: true,
columns: [
{
flex: 1,
xtype: 'treecolumn',
cell: {
xtype: 'widgetTreeCell',
cls: 'js-ucan-comment-ucan-widget-tree-cell ucan-comment-ucan-widget-tree-cell',
iconCls: 'ucan-comment-hide-icon',
encodeHtml: false,
viewModel: true,
reference: 'widgetTreeCell',
publishes: ['record'],
widget: {
xtype: 'panel',
cls: 'js-ucan-comment-panel',
border: true,
height: 'auto',
defaultBindProperty: 'html',
viewModel: {
formulas: {
formatDate: function(get) {
const dateFormat = get('translator').data.date_time_format;
return Ext.util.Format.date(get('widgetTreeCell.record.created'), dateFormat);
},
extractCreator: function(get) {
const creator = get('widgetTreeCell.record.creator');
const groups = creator.match(/sn=([\w\xC4-\xFC-]*),fn=([\w\xC4-\xFC-]*)/);
if (groups) {
return groups[2] + ' ' + groups[1];
} else {
return creator;
}
},
checkDeprecatedComment: function(get) {
const contextId = this.getView().up('comment').getContextId();
const commentDeprecated = get('widgetTreeCell.record.contextId') !== contextId;
if (commentDeprecated && !Ext.isEmpty(contextId)) {
return '<i class="x-fa fa-exclamation-triangle" title="' + get('translator.comment_deprecated_tooltip') + '">';
} else {
return '';
}
},
setCommentTypeCls: function(get) {
const commentType = get('widgetTreeCell.record.type');
if (commentType === 'REVIEW') {
return 'ucan-review-comment';
} else if (commentType === 'STATISTIC') {
return 'ucan-statistic-comment';
} else {
return 'ucan-default-comment';
}
}
}
},
flex: 1,
bind: {
title: '<span class="ucan-comment-panel-title-creator">{extractCreator}</span> '
+ '<span class="ucan-comment-panel-title-created">{formatDate}</span> '
+ '<span>{checkDeprecatedComment}</span>',
cls: 'js-ucan-comment-panel ucan-comment-panel {setCommentTypeCls}'
},
items: [
{
xtype: 'displayfield',
cls: 'ucan-comment-displayfield-comment-content',
width: '100%',
bind: {
value: '{widgetTreeCell.record.text}',
hidden: '{widgetTreeCell.record.editMode}'
},
encodeHtml: false
},
{
xtype: 'commentEditorContainer',
bind: {
comment: '{widgetTreeCell.record}',
translator: '{translator}',
edit: '{edit}',
hidden: '{!widgetTreeCell.record.editMode}'
}
}
],
tools: [
{
cls: 'js-ucan-comment-button-reply ucan-comment-button-reply',
bind: {
hidden: '{widgetTreeCell.record.newlyAdded}'
},
iconCls: 'x-fa fa-reply',
handler: 'onReplyToComment'
}
]
}
}
}
]
},
{
xtype: 'displayfield',
cls: 'js-ucan-comment-displayfield-warning-disabled ucan-warning-component',
hidden: true
}
],
updateComments: function(config) {
const commentTree = SinkUtil.downClassFromView(this, 'js-ucan-comment-tree');
if (!Ext.isEmpty(config)) {
commentTree.setStore(config);
commentTree.expandAll();
} else {
commentTree.setStore(Ext.create('Ext.data.TreeStore', {
rootVisible: false,
parentIdProperty: 'parentId'
}));
}
},
updateTranslator: function(config) {
this.down('[cls~=js-ucan-comment-button-add]').setText(config.get('comment_new'));
this.down('[cls~=js-ucan-comment-button-filter-review]').setTooltip(config.get('comments_filter_review'));
this.down('[cls~=js-ucan-comment-button-filter-statistic]').setTooltip(config.get('comments_filter_ex3'));
this.down('[cls~=js-ucan-comment-button-filter-default]').setTooltip(config.get('comments_filter_default'));
this.down('[cls~=js-ucan-comment-label-filter]').setHtml(config.get('filter'));
this.query('[cls~=js-ucan-comment-ucan-widget-tree-cell] [cls~=js-ucan-comment-button-reply]').forEach(replyButton => {
replyButton.setTooltip(config.get('comment_reply_tooltip'));
});
SinkUtil.downClassFromView(this, 'js-ucan-comment-displayfield-warning-disabled').setHtml('<i class="x-fa fa-exclamation-triangle">' + config.get('comment_disabled_warning'));
},
getButtonHiddenFromCurrentUser: function(button) {
return button.up('[cls~=js-ucan-comment-ucan-widget-tree-cell]').getRecord().get('owner') !== parseInt(this.getCurrentUser().get('id'));
},
preprocessComments: function(comments) {
comments.forEach(comment => this.recurseComment(comment));
},
recurseComment: function(comment) {
if (!Ext.isEmpty(comment.comments)) {
comment.comments.forEach(childComment => this.recurseComment(childComment));
} else {
comment.leaf = true;
}
},
onReplyToComment: function(panel) {
const commentsStore = this.down('[cls~=js-ucan-comment-tree]').getStore();
const editModeComment = commentsStore.findRecord('editMode', true);
if (Ext.isEmpty(editModeComment)) {
let newComment = Ext.create('Ext.data.TreeModel', {
creator: this.getCurrentUser().get('name'),
language: this.getCurrentUser().get('language'),
text: '',
name: 'newComment',
parentId: panel.up('[cls~=js-ucan-comment-ucan-widget-tree-cell]').getRecord().getId(),
leaf: true,
expanded: true,
newlyAdded: true,
created: new Date().toISOString(),
contextId: this.getContextId(),
contextEntityId: this.getContextEntityId(),
type: this.getType(),
editMode: true
});
panel.up('[cls~=js-ucan-comment-ucan-widget-tree-cell]').getRecord().appendChild(newComment);
commentsStore.add(newComment);
}
},
onCancelComment: function(button) {
let comment = button.up('[cls~=js-ucan-comment-editor-container]').getComment();
if (comment.get('text') === '' && comment.get('newlyAdded')) {
this.down('[cls~=js-ucan-comment-tree]').getStore().remove(comment);
}
this.onDestroyContainer(button);
},
onDestroyContainer: function(button) {
button.up('[cls~=js-ucan-comment-editor-container]').destroy();
},
onSubmitComment: function(button) {
const commentEditorContainer = button.up('[cls~=js-ucan-comment-editor-container]');
const comment = commentEditorContainer.getComment();
comment.set('text',
commentEditorContainer.down('[cls~=js-ucan-comment-editor-container-ucan-native-froala-value]').getFroalaEditor().html.get());
comment.set('newlyAdded', false);
comment.set('editMode', false);
if (commentEditorContainer.getEdit()) {
this.fireEvent('commentEdited', comment, this.down('#commentTree'));
} else {
this.down('[cls~=js-ucan-comment-tree]').expandAll();
this.fireEvent('commentAdded', comment, this.down('#commentTree'));
}
commentEditorContainer.destroy();
this.down('[cls~=js-ucan-comment-tree]').collapseAll();
this.down('[cls~=js-ucan-comment-tree]').expandAll();
this.getCommentAddButton().setPressed(false);
},
onAddNewComment: function(button) {
const commentsStore = this.down('[cls~=js-ucan-comment-tree]').getStore();
const editModeComment = commentsStore.findRecord('editMode', true);
if (button.isPressed()) {
if (Ext.isEmpty(editModeComment)) {
let newComment = Ext.create('Ext.data.TreeModel', {
creator: this.getCurrentUser().get('name'),
language: this.getCurrentUser().get('language'),
text: '',
name: 'newComment',
parentId: commentsStore.getRoot().getId(),
leaf: true,
expanded: true,
newlyAdded: true,
created: new Date().toISOString(),
contextId: this.getContextId(),
contextEntityId: this.getContextEntityId(),
type: this.getType(),
editMode: true
});
commentsStore.getRoot().appendChild(newComment);
commentsStore.add(newComment);
this.getScrollable().scrollTo(0, this.getSize().height, true);
}
} else {
editModeComment.erase();
}
},
onToggleReviewFilter: function() {
this.getComments().clearFilter();
this.getCommentAddButton().hide();
this.getComments().filter('type', 'REVIEW');
},
onToggleStatisticFilter: function() {
this.getComments().clearFilter();
this.getCommentAddButton().hide();
this.getComments().filter('type', 'STATISTIC');
},
onToggleDefaultFilter: function() {
this.getCommentAddButton().show();
this.getComments().clearFilter();
},
onChangeCommentFilter: function(_segmentedbutton, button, pressed) {
const value = button.getValue();
if (value === 'REVIEW') {
this.onToggleReviewFilter(pressed);
} else if (value === 'STATISTIC') {
this.onToggleStatisticFilter(pressed);
} else {
this.onToggleDefaultFilter(pressed);
}
},
updateContextId: function(config) {
if (Ext.isEmpty(config) || !Number.isInteger(config)) {
SinkUtil.downClassFromView(this, 'js-ucan-comment-displayfield-warning-disabled').setHidden(false);
SinkUtil.downClassFromView(this, 'js-ucan-comment-button-add').setDisabled(true);
} else {
SinkUtil.downClassFromView(this, 'js-ucan-comment-displayfield-warning-disabled').setHidden(true);
SinkUtil.downClassFromView(this, 'js-ucan-comment-button-add').setDisabled(false);
}
},
setContextId: function(contextId) {
this._contextId = contextId;
this.updateContextId(contextId);
},
getCommentAddButton: function() {
return SinkUtil.downClassFromView(this, 'js-ucan-comment-button-add');
}
});