snapshot of https://github.com/espocrm/espocrm.git (master, 2026-09-18; blobs > 131072B omitted)
Some checks failed
Test / Test on PHP 8.3 (push) Failing after 5s
Test / Test on PHP 8.4 (push) Failing after 4s
Test / Test on PHP 8.5 (push) Failing after 3s
TypeScript static analysis / TypeScript check (push) Failing after 14s
Test Integration on MySQL / Test on PHP 8.3 (push) Failing after 1s
Test Integration on MySQL / Test on PHP 8.5 (push) Failing after 1s
Test Integration on PostgreSQL / Test on PHP 8.4 fix (push) Failing after 1s
Test Integration on PostgreSQL / Test on PHP 8.4 master (push) Failing after 1s
276
client/css/cropper.css
Normal file
@@ -0,0 +1,276 @@
|
||||
/*!
|
||||
* Cropper v0.7.4-beta
|
||||
* https://github.com/fengyuanchen/cropper
|
||||
*
|
||||
* Copyright 2014 Fengyuan Chen
|
||||
* Released under the MIT license
|
||||
*/
|
||||
|
||||
.cropper-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-touch-callout: none;
|
||||
}
|
||||
|
||||
.cropper-container img {
|
||||
width: 100%;
|
||||
max-width: none !important;
|
||||
height: 100%;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
.cropper-modal,
|
||||
.cropper-canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.cropper-canvas {
|
||||
background-color: #fff;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cropper-modal {
|
||||
background-color: #000;
|
||||
filter: alpha(opacity=50);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.cropper-dragger {
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
left: 10%;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
.cropper-viewer {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
outline-color: #69f;
|
||||
outline-color: rgba(51, 102, 255, .75);
|
||||
}
|
||||
|
||||
.cropper-dashed {
|
||||
position: absolute;
|
||||
display: block;
|
||||
filter: alpha(opacity=50);
|
||||
border: 0 dashed #fff;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.cropper-dashed.dashed-h {
|
||||
top: 33.3%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 33.3%;
|
||||
border-top-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.cropper-dashed.dashed-v {
|
||||
top: 0;
|
||||
left: 33.3%;
|
||||
width: 33.3%;
|
||||
height: 100%;
|
||||
border-right-width: 1px;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.cropper-face,
|
||||
.cropper-line,
|
||||
.cropper-point {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: alpha(opacity=10);
|
||||
opacity: .1;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
top: 0;
|
||||
left: 0;
|
||||
cursor: move;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.cropper-line {
|
||||
background-color: #69f;
|
||||
}
|
||||
|
||||
.cropper-line.line-e {
|
||||
top: 0;
|
||||
right: -3px;
|
||||
width: 5px;
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.cropper-line.line-n {
|
||||
top: -3px;
|
||||
left: 0;
|
||||
height: 5px;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.cropper-line.line-w {
|
||||
top: 0;
|
||||
left: -3px;
|
||||
width: 5px;
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
.cropper-line.line-s {
|
||||
bottom: -3px;
|
||||
left: 0;
|
||||
height: 5px;
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.cropper-point {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #69f;
|
||||
filter: alpha(opacity=75);
|
||||
opacity: .75;
|
||||
}
|
||||
|
||||
.cropper-point.point-e {
|
||||
top: 50%;
|
||||
right: -3px;
|
||||
margin-top: -3px;
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-n {
|
||||
top: -3px;
|
||||
left: 50%;
|
||||
margin-left: -3px;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-w {
|
||||
top: 50%;
|
||||
left: -3px;
|
||||
margin-top: -3px;
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-s {
|
||||
bottom: -3px;
|
||||
left: 50%;
|
||||
margin-left: -3px;
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-ne {
|
||||
top: -3px;
|
||||
right: -3px;
|
||||
cursor: ne-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-nw {
|
||||
top: -3px;
|
||||
left: -3px;
|
||||
cursor: nw-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-sw {
|
||||
bottom: -3px;
|
||||
left: -3px;
|
||||
cursor: sw-resize;
|
||||
}
|
||||
|
||||
.cropper-point.point-se {
|
||||
right: -3px;
|
||||
bottom: -3px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: se-resize;
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.cropper-point.point-se:before {
|
||||
position: absolute;
|
||||
right: -50%;
|
||||
bottom: -50%;
|
||||
display: block;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
content: " ";
|
||||
background-color: #69f;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.cropper-point.point-se {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.cropper-point.point-se {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.cropper-point.point-se {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
filter: alpha(opacity=75);
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper classes for JavaScript */
|
||||
|
||||
.cropper-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cropper-invisible {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
width: auto !important;
|
||||
max-width: none !important;
|
||||
height: auto !important;
|
||||
max-height: none !important;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cropper-move {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.cropper-crop {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.cropper-disabled .cropper-canvas,
|
||||
.cropper-disabled .cropper-face,
|
||||
.cropper-disabled .cropper-line,
|
||||
.cropper-disabled .cropper-point {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
210
client/css/misc/layout-manager-grid.css
Normal file
@@ -0,0 +1,210 @@
|
||||
#layout ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#layout ul > li {
|
||||
background-color: var(--select-item-bg);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
#layout ul.panels > li {
|
||||
padding: var(--5px) var(--10px);
|
||||
margin-bottom: var(--14px);
|
||||
min-height: var(--80px);
|
||||
border: var(--1px) solid var(--select-item-border);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--panel-bg);
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#layout ul.panels > li .panel-label {
|
||||
margin-left: var(--4px);
|
||||
}
|
||||
|
||||
#layout ul.panels > li[data-tab-break="true"] {
|
||||
margin-top: var(--28px);
|
||||
}
|
||||
|
||||
#layout ul.panels > li[data-tab-break="true"]:before {
|
||||
content: " ";
|
||||
display: block;
|
||||
height: var(--1px);
|
||||
background-color: var(--gray-light);
|
||||
position: relative;
|
||||
top: calc(var(--20px) * -1);
|
||||
width: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#layout ul.rows {
|
||||
min-height: var(--20px);
|
||||
}
|
||||
|
||||
#layout ul.rows > li {
|
||||
list-style: none;
|
||||
border: var(--1px) solid var(--select-item-border);
|
||||
background-color: var(--panel-bg);
|
||||
border-radius: var(--border-radius);
|
||||
margin: var(--8px) 0;
|
||||
padding: var(--5px);
|
||||
height: calc(var(--70px) + var(--2px));
|
||||
}
|
||||
|
||||
#layout ul.cells {
|
||||
min-height: var(--30px);
|
||||
margin-top: var(--12px);
|
||||
|
||||
width: calc(100% - var(--20px));
|
||||
}
|
||||
|
||||
#layout ul.panels ul.cells > li {
|
||||
width: calc(50% - var(--10px));
|
||||
float: left;
|
||||
}
|
||||
|
||||
#layout {
|
||||
.cells {
|
||||
.cell {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#layout ul.panels ul.cells > li[data-full-width="true"] {
|
||||
width: calc(100% - var(--10px));
|
||||
}
|
||||
|
||||
#layout ul.panels ul.cells[data-cell-count="1"] > li {
|
||||
width: calc(100% - var(--10px));
|
||||
}
|
||||
|
||||
#layout ul.panels ul.cells[data-cell-count="2"] > li {
|
||||
width: calc(50% - var(--10px));
|
||||
}
|
||||
|
||||
#layout ul.panels ul.cells[data-cell-count="3"] > li {
|
||||
width: calc(33.3% - var(--10px));
|
||||
}
|
||||
|
||||
#layout ul.panels ul.cells[data-cell-count="4"] > li {
|
||||
width: calc(25% - var(--10px));
|
||||
}
|
||||
|
||||
#layout ul.cells > li {
|
||||
list-style: none;
|
||||
border: var(--1px) solid var(--select-item-border);
|
||||
margin: var(--5px);
|
||||
padding: var(--5px);
|
||||
height: var(--34px);
|
||||
}
|
||||
|
||||
#layout ul.cells > li.ui-state-hover {
|
||||
border-color: var(--brand-primary);
|
||||
}
|
||||
|
||||
#layout ul.cells.disabled > li {
|
||||
margin: var(--5px) 0;
|
||||
}
|
||||
|
||||
#layout ul.rows > li > div {
|
||||
|
||||
}
|
||||
|
||||
#layout ul.disabled {
|
||||
min-height: var(--200px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#layout ul.disabled > li a {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#layout header {
|
||||
font-weight: 600;
|
||||
margin-bottom: var(--10px);
|
||||
}
|
||||
|
||||
#layout ul.panels > li label {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#layout ul.panels > li header a {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#layout ul.panels > li > div {
|
||||
width: auto;
|
||||
text-align: left;
|
||||
margin-left: var(--5px);
|
||||
}
|
||||
|
||||
ul.cells li.cell a.remove-field {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.cells li.cell:hover a.remove-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.cells[data-cell-count="1"] li.cell:hover a.remove-field[data-action="minusCell"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.panels > li a.remove-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.panels > li:hover a.remove-panel {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.rows > li a.remove-row {
|
||||
display: none;
|
||||
width: var(--5px);
|
||||
height: var(--5px);
|
||||
}
|
||||
|
||||
ul.rows > li:hover a.remove-row {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.rows > li a.add-cell {
|
||||
display: none;
|
||||
position: relative;
|
||||
width: var(--5px);
|
||||
height: var(--5px);
|
||||
top: var(--19px);
|
||||
right: var(--7px);
|
||||
}
|
||||
|
||||
ul.rows > li:hover a.add-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.rows > li[data-cell-count="4"]:hover a.add-cell {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.panels > li a.edit-panel-label {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
ul.panels > li:hover a.edit-panel-label {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.row-actions {
|
||||
float: right;
|
||||
height: var(--50px);
|
||||
width: var(--12px);
|
||||
}
|
||||
|
||||
.cell.ui-draggable-dragging {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#layout .well:focus-visible {
|
||||
outline: 0;
|
||||
}
|
||||
61
client/css/misc/layout-manager-rows.css
Normal file
@@ -0,0 +1,61 @@
|
||||
#layout ul {
|
||||
width: 100%;
|
||||
min-height: var(--100px);
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#layout ul li {
|
||||
list-style: none;
|
||||
border: var(--1px) solid var(--select-item-border);
|
||||
margin: var(--5px) 0;
|
||||
padding: var(--5px);
|
||||
height: var(--34px);
|
||||
}
|
||||
|
||||
#layout header {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#layout ul > li .left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#layout ul > li {
|
||||
background-color: var(--select-item-bg);
|
||||
color: var(--select-item-text-color);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
#layout ul.enabled > li .right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#layout ul.disabled > li .right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#layout ul > li .width {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
#layout ul.disabled > li .width {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#layout label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.enabled li a.edit-field {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.enabled li:hover a.edit-field {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#layout .well:focus-visible {
|
||||
outline: 0;
|
||||
}
|
||||
3
client/custom/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
!modules
|
||||
3
client/custom/modules/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
!dummy.txt
|
||||
1
client/custom/modules/dummy.txt
Normal file
@@ -0,0 +1 @@
|
||||
dummy
|
||||
BIN
client/fonts/fa-brands-400.woff2
Normal file
BIN
client/fonts/fa-regular-400.ttf
Normal file
BIN
client/fonts/fa-regular-400.woff2
Normal file
BIN
client/fonts/fa-v4compatibility.ttf
Normal file
BIN
client/fonts/fa-v4compatibility.woff2
Normal file
BIN
client/fonts/glyphicons-halflings-regular.ttf
Normal file
BIN
client/fonts/glyphicons-halflings-regular.woff
Normal file
BIN
client/fonts/glyphicons-halflings-regular.woff2
Normal file
BIN
client/fonts/inter/Inter-Black.woff2
Normal file
BIN
client/fonts/inter/Inter-BlackItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-Bold.woff2
Normal file
BIN
client/fonts/inter/Inter-BoldItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-ExtraBold.woff2
Normal file
BIN
client/fonts/inter/Inter-ExtraBoldItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-ExtraLight.woff2
Normal file
BIN
client/fonts/inter/Inter-ExtraLightItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-Italic.woff2
Normal file
BIN
client/fonts/inter/Inter-Light.woff2
Normal file
BIN
client/fonts/inter/Inter-LightItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-Medium.woff2
Normal file
BIN
client/fonts/inter/Inter-MediumItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-Regular.woff2
Normal file
BIN
client/fonts/inter/Inter-SemiBold.woff2
Normal file
BIN
client/fonts/inter/Inter-SemiBoldItalic.woff2
Normal file
BIN
client/fonts/inter/Inter-Thin.woff2
Normal file
BIN
client/fonts/inter/Inter-ThinItalic.woff2
Normal file
92
client/fonts/inter/LICENSE.txt
Normal file
@@ -0,0 +1,92 @@
|
||||
Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION AND CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
client/fonts/jet-brains-mono/JetBrainsMono-Italic.woff2
Normal file
BIN
client/fonts/jet-brains-mono/JetBrainsMono-Regular.woff2
Normal file
93
client/fonts/jet-brains-mono/OFL.txt
Normal file
@@ -0,0 +1,93 @@
|
||||
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
client/fonts/summernote.ttf
Normal file
BIN
client/fonts/summernote.woff
Normal file
BIN
client/fonts/summernote.woff2
Normal file
BIN
client/img/favicon-196.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
client/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
81
client/img/favicon.svg
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 8.4666665 8.4666665"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="favicon-32.svg"
|
||||
inkscape:export-filename="favicon-32.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="22.15625"
|
||||
inkscape:cy="21.125"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="971"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" /><defs
|
||||
id="defs2" /><g
|
||||
inkscape:label="icon"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"><circle
|
||||
style="fill:#94a1b6;fill-opacity:1;stroke:none;stroke-width:0.264644;stroke-dasharray:none;stroke-opacity:0.196891"
|
||||
id="path3857"
|
||||
cx="4.2391791"
|
||||
cy="4.2440238"
|
||||
inkscape:label="circle"
|
||||
r="4.2198539" /><g
|
||||
style="overflow:visible;fill:#ffffff;fill-opacity:1"
|
||||
id="g165"
|
||||
transform="matrix(0.23872556,0,0,0.25044154,-18.034354,5.1243882)"
|
||||
inkscape:label="letter"><switch
|
||||
transform="matrix(1.089,0,0,1.089,-0.89733,-0.52658)"
|
||||
id="switch148"
|
||||
style="fill:#ffffff;fill-opacity:1">
|
||||
<foreignObject
|
||||
width="1"
|
||||
height="1"
|
||||
requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||
</foreignObject>
|
||||
<g
|
||||
transform="matrix(0.96767,0,0,0.96767,3.9659,-1.2011)"
|
||||
id="g146"
|
||||
style="fill:#ffffff;fill-opacity:1">
|
||||
|
||||
|
||||
<g
|
||||
fill="#ffffff"
|
||||
id="g144"
|
||||
transform="matrix(0.53332351,0,0,0.52516097,68.999419,-22.209109)"
|
||||
style="fill:#ffffff;fill-opacity:1">
|
||||
<path
|
||||
d="M 45.672,58.148 H 27.146 c -2.861,0 -5.614,-0.651 -8.257,-1.953 -2.861,-1.409 -5.043,-3.651 -6.547,-6.725 -1.503,-3.074 -2.254,-6.455 -2.254,-10.145 0,-3.652 0.724,-6.961 2.173,-9.926 1.594,-3.219 3.803,-5.569 6.628,-7.052 1.557,-0.795 3.052,-1.355 4.482,-1.682 1.43,-0.325 3.07,-0.488 4.917,-0.488 h 17.168 v 6.789 H 29.57 c -1.415,0 -2.602,0.187 -3.563,0.558 -0.961,0.372 -1.912,1.037 -2.855,1.994 -0.943,0.957 -1.597,1.887 -1.959,2.791 -0.363,0.902 -0.543,2.027 -0.543,3.375 h 25.023 v 6.789 H 20.648 c 0,1.24 0.164,2.325 0.491,3.256 0.327,0.93 0.919,1.887 1.776,2.871 0.856,0.985 1.749,1.732 2.677,2.242 0.929,0.512 2.03,0.767 3.306,0.767 h 16.774 z"
|
||||
id="path136"
|
||||
style="fill:#ffffff;fill-opacity:1" />
|
||||
|
||||
|
||||
|
||||
</g>
|
||||
</g>
|
||||
</switch></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
BIN
client/img/logo-33.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
client/img/logo-37.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
client/img/logo-39.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
17
client/img/logo-light.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="318" height="78" enable-background="new 0 0 307.813 75" overflow="visible" version="1.1" viewBox="0 0 318 78" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||
<switch transform="matrix(1.089 0 0 1.089 -.89733 -.52658)">
|
||||
<foreignObject width="1" height="1" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||
</foreignObject>
|
||||
<g transform="matrix(.96767 0 0 .96767 3.9659 -1.2011)">
|
||||
<path d="m169.53 21.864c-7.453 2.972-9.569 11.987-9.005 19.212 1.587 2.982 3.845 5.562 5.783 8.312l4.262-1.083c-1.796-4.447-1.689-9.424-0.806-14.066 0.585-3.001 2.309-6.476 5.634-7.032 5.307-0.847 10.733-0.271 16.088-0.369 0.091-2.196 0.115-4.392 0.107-6.585-7.333 0.387-15.043-1.038-22.063 1.611zm52.714-1.294c-8.12-0.952-16.332-0.149-24.492-0.387-0.021 6.43-3e-3 12.854 0.078 19.274 2.625-0.849 5.251-1.739 7.909-2.532 0.042-3.272 0.028-6.527-0.071-9.789 4.869-0.029 9.874-0.757 14.639 0.451 1.838 0.298 2.051 2.25 2.687 3.641 2.541-0.891 5.111-1.717 7.672-2.574-0.703-4.246-4.129-7.633-8.422-8.084zm23.522-0.593c-3.954 0.072-7.912 0.064-11.864 0.047 0.051 2.544 0.063 5.074 0.072 7.617 4.263-1.482 8.553-2.889 12.848-4.268-0.35-1.128-0.706-2.268-1.056-3.396z" fill="#8AA0C2"/>
|
||||
<path d="m161.96 69.125c7.886-3.717 15.757-7.463 23.72-11.018 5.563 0.359 11.146 0.021 16.722 0.193 1.14-0.036 2.292-0.061 3.432-0.088-0.011-3.195-0.025-6.38-0.082-9.564 3.428-1.502 10.227-4.623 10.227-4.623l15.215 13.941 11.096 0.106-0.715-26.236 0.803-0.211 9.005 26.344 8.834-0.066 8.99-28.394-0.308 28.434 8.074-0.021-0.231-37.932-9.279 0.071 30.625-14.141s-37.593 14.279-56.404 21.385c-2.996 1.022-5.878 2.315-8.853 3.394-2.278 0.867-4.558 1.713-6.834 2.58-20.071 7.526-39.945 15.604-60.126 22.803-6.777-10.522-15.314-19.854-21.768-30.585zm72.116-17.961c-0.108 0.154-0.324 0.458-0.429 0.611-3.448-3.018-6.765-6.189-10.21-9.205 1.745-1.096 3.47-2.242 5.026-3.597 1.625-1.386 3.479-2.469 5.345-3.499 0.293 5.227 0.258 10.452 0.268 15.69zm23.942-9.67c-0.857 2.578-1.825 5.137-2.793 7.682-1.644-6.217-3.94-12.238-5.856-18.383-0.119-0.52-0.366-1.574-0.487-2.093 3.428-1.709 10.585-4.854 15.229-6.815-1.647 5.969-4.306 14.029-6.093 19.609z" fill="#9faabd"/>
|
||||
<g fill="#8AA0C2">
|
||||
<path d="m45.672 58.148h-18.526c-2.861 0-5.614-0.651-8.257-1.953-2.861-1.409-5.043-3.651-6.547-6.725-1.503-3.074-2.254-6.455-2.254-10.145 0-3.652 0.724-6.961 2.173-9.926 1.594-3.219 3.803-5.569 6.628-7.052 1.557-0.795 3.052-1.355 4.482-1.682 1.43-0.325 3.07-0.488 4.917-0.488h17.168v6.789h-15.886c-1.415 0-2.602 0.187-3.563 0.558-0.961 0.372-1.912 1.037-2.855 1.994s-1.597 1.887-1.959 2.791c-0.363 0.902-0.543 2.027-0.543 3.375h25.023v6.789h-25.025c0 1.24 0.164 2.325 0.491 3.256 0.327 0.93 0.919 1.887 1.776 2.871 0.856 0.985 1.749 1.732 2.677 2.242 0.929 0.512 2.03 0.767 3.306 0.767h16.774z"/>
|
||||
<path d="m76.499 49.519c0 2.397-0.771 4.449-2.312 6.154-1.541 1.706-3.49 2.56-5.846 2.56h-18.653v-5.113h15.326c1.087 0 2.001-0.272 2.744-0.817s1.115-1.327 1.115-2.345c0-2.362-1.595-3.543-4.783-3.543h-7.825c-1.666 0-3.278-0.79-4.836-2.369-1.559-1.58-2.336-3.287-2.336-5.119 0-2.585 0.579-4.667 1.738-6.248 1.34-1.794 3.313-2.692 5.922-2.692h17.928v5.364h-15.938c-0.614 0-1.147 0.289-1.599 0.868s-0.677 1.235-0.677 1.972c0 0.807 0.298 1.498 0.896 2.076 0.597 0.579 1.311 0.867 2.144 0.867h8.415c2.643 0 4.733 0.79 6.271 2.369 1.536 1.579 2.306 3.584 2.306 6.016z"/>
|
||||
<path d="m109.29 43.414c0 4.495-1.166 8.074-3.497 10.738s-5.395 3.996-9.188 3.996h-8.186v10.309h-7.627v-38.472h15.09c4.27 0 7.6 1.269 9.989 3.806 2.279 2.428 3.419 5.637 3.419 9.623zm-7.627 0.405c0-2.356-0.754-4.286-2.262-5.793-1.509-1.505-3.388-2.258-5.641-2.258h-5.341v16.429h5.886c2.179 0 3.951-0.771 5.313-2.313 1.363-1.54 2.045-3.562 2.045-6.065z"/>
|
||||
<path d="m145.1 43.967c0 4.896-1.557 8.65-4.669 11.261-2.86 2.394-6.751 3.591-11.673 3.591-4.923 0-8.742-1.087-11.456-3.264-3.15-2.502-4.724-6.401-4.724-11.696 0-4.424 1.701-7.906 5.104-10.446 3.04-2.283 6.786-3.427 11.238-3.427 4.887 0 8.805 1.225 11.754 3.673s4.426 5.884 4.426 10.308zm-8.382-0.065c0-2.285-0.716-4.197-2.146-5.738-1.432-1.54-3.379-2.312-5.841-2.312-2.246 0-4.103 0.79-5.57 2.366-1.467 1.577-2.2 3.563-2.2 5.955 0 2.756 0.743 4.949 2.228 6.581s3.405 2.448 5.76 2.448c2.679 0 4.673-0.852 5.977-2.557 1.193-1.557 1.792-3.805 1.792-6.743z"/>
|
||||
</g>
|
||||
</g>
|
||||
</switch>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
17
client/img/logo-lite.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="318" height="78" enable-background="new 0 0 307.813 75" overflow="visible" version="1.1" viewBox="0 0 318 78" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||
<switch transform="matrix(1.089 0 0 1.089 -.89733 -.52658)">
|
||||
<foreignObject width="1" height="1" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||
</foreignObject>
|
||||
<g transform="matrix(.96767 0 0 .96767 3.9659 -1.2011)">
|
||||
<path d="m169.53 21.864c-7.453 2.972-9.569 11.987-9.005 19.212 1.587 2.982 3.845 5.562 5.783 8.312l4.262-1.083c-1.796-4.447-1.689-9.424-0.806-14.066 0.585-3.001 2.309-6.476 5.634-7.032 5.307-0.847 10.733-0.271 16.088-0.369 0.091-2.196 0.115-4.392 0.107-6.585-7.333 0.387-15.043-1.038-22.063 1.611zm52.714-1.294c-8.12-0.952-16.332-0.149-24.492-0.387-0.021 6.43-3e-3 12.854 0.078 19.274 2.625-0.849 5.251-1.739 7.909-2.532 0.042-3.272 0.028-6.527-0.071-9.789 4.869-0.029 9.874-0.757 14.639 0.451 1.838 0.298 2.051 2.25 2.687 3.641 2.541-0.891 5.111-1.717 7.672-2.574-0.703-4.246-4.129-7.633-8.422-8.084zm23.522-0.593c-3.954 0.072-7.912 0.064-11.864 0.047 0.051 2.544 0.063 5.074 0.072 7.617 4.263-1.482 8.553-2.889 12.848-4.268-0.35-1.128-0.706-2.268-1.056-3.396z" fill="#fff"/>
|
||||
<path d="m161.96 69.125c7.886-3.717 15.757-7.463 23.72-11.018 5.563 0.359 11.146 0.021 16.722 0.193 1.14-0.036 2.292-0.061 3.432-0.088-0.011-3.195-0.025-6.38-0.082-9.564 3.428-1.502 10.227-4.623 10.227-4.623l15.215 13.941 11.096 0.106-0.715-26.236 0.803-0.211 9.005 26.344 8.834-0.066 8.99-28.394-0.308 28.434 8.074-0.021-0.231-37.932-9.279 0.071 30.625-14.141s-37.593 14.279-56.404 21.385c-2.996 1.022-5.878 2.315-8.853 3.394-2.278 0.867-4.558 1.713-6.834 2.58-20.071 7.526-39.945 15.604-60.126 22.803-6.777-10.522-15.314-19.854-21.768-30.585zm72.116-17.961c-0.108 0.154-0.324 0.458-0.429 0.611-3.448-3.018-6.765-6.189-10.21-9.205 1.745-1.096 3.47-2.242 5.026-3.597 1.625-1.386 3.479-2.469 5.345-3.499 0.293 5.227 0.258 10.452 0.268 15.69zm23.942-9.67c-0.857 2.578-1.825 5.137-2.793 7.682-1.644-6.217-3.94-12.238-5.856-18.383-0.119-0.52-0.366-1.574-0.487-2.093 3.428-1.709 10.585-4.854 15.229-6.815-1.647 5.969-4.306 14.029-6.093 19.609z" fill="#e8e9eb"/>
|
||||
<g fill="#fff">
|
||||
<path d="m45.672 58.148h-18.526c-2.861 0-5.614-0.651-8.257-1.953-2.861-1.409-5.043-3.651-6.547-6.725-1.503-3.074-2.254-6.455-2.254-10.145 0-3.652 0.724-6.961 2.173-9.926 1.594-3.219 3.803-5.569 6.628-7.052 1.557-0.795 3.052-1.355 4.482-1.682 1.43-0.325 3.07-0.488 4.917-0.488h17.168v6.789h-15.886c-1.415 0-2.602 0.187-3.563 0.558-0.961 0.372-1.912 1.037-2.855 1.994s-1.597 1.887-1.959 2.791c-0.363 0.902-0.543 2.027-0.543 3.375h25.023v6.789h-25.025c0 1.24 0.164 2.325 0.491 3.256 0.327 0.93 0.919 1.887 1.776 2.871 0.856 0.985 1.749 1.732 2.677 2.242 0.929 0.512 2.03 0.767 3.306 0.767h16.774z"/>
|
||||
<path d="m76.499 49.519c0 2.397-0.771 4.449-2.312 6.154-1.541 1.706-3.49 2.56-5.846 2.56h-18.653v-5.113h15.326c1.087 0 2.001-0.272 2.744-0.817s1.115-1.327 1.115-2.345c0-2.362-1.595-3.543-4.783-3.543h-7.825c-1.666 0-3.278-0.79-4.836-2.369-1.559-1.58-2.336-3.287-2.336-5.119 0-2.585 0.579-4.667 1.738-6.248 1.34-1.794 3.313-2.692 5.922-2.692h17.928v5.364h-15.938c-0.614 0-1.147 0.289-1.599 0.868s-0.677 1.235-0.677 1.972c0 0.807 0.298 1.498 0.896 2.076 0.597 0.579 1.311 0.867 2.144 0.867h8.415c2.643 0 4.733 0.79 6.271 2.369 1.536 1.579 2.306 3.584 2.306 6.016z"/>
|
||||
<path d="m109.29 43.414c0 4.495-1.166 8.074-3.497 10.738s-5.395 3.996-9.188 3.996h-8.186v10.309h-7.627v-38.472h15.09c4.27 0 7.6 1.269 9.989 3.806 2.279 2.428 3.419 5.637 3.419 9.623zm-7.627 0.405c0-2.356-0.754-4.286-2.262-5.793-1.509-1.505-3.388-2.258-5.641-2.258h-5.341v16.429h5.886c2.179 0 3.951-0.771 5.313-2.313 1.363-1.54 2.045-3.562 2.045-6.065z"/>
|
||||
<path d="m145.1 43.967c0 4.896-1.557 8.65-4.669 11.261-2.86 2.394-6.751 3.591-11.673 3.591-4.923 0-8.742-1.087-11.456-3.264-3.15-2.502-4.724-6.401-4.724-11.696 0-4.424 1.701-7.906 5.104-10.446 3.04-2.283 6.786-3.427 11.238-3.427 4.887 0 8.805 1.225 11.754 3.673s4.426 5.884 4.426 10.308zm-8.382-0.065c0-2.285-0.716-4.197-2.146-5.738-1.432-1.54-3.379-2.312-5.841-2.312-2.246 0-4.103 0.79-5.57 2.366-1.467 1.577-2.2 3.563-2.2 5.955 0 2.756 0.743 4.949 2.228 6.581s3.405 2.448 5.76 2.448c2.679 0 4.673-0.852 5.977-2.557 1.193-1.557 1.792-3.805 1.792-6.743z"/>
|
||||
</g>
|
||||
</g>
|
||||
</switch>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
BIN
client/img/logo.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
17
client/img/logo.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="318" height="78" enable-background="new 0 0 307.813 75" overflow="visible" version="1.1" viewBox="0 0 318 78" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||
<switch transform="matrix(1.089 0 0 1.089 -.89733 -.52658)">
|
||||
<foreignObject width="1" height="1" requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||
</foreignObject>
|
||||
<g transform="matrix(.96767 0 0 .96767 3.9659 -1.2011)">
|
||||
<path d="m169.53 21.864c-7.453 2.972-9.569 11.987-9.005 19.212 1.587 2.982 3.845 5.562 5.783 8.312l4.262-1.083c-1.796-4.447-1.689-9.424-0.806-14.066 0.585-3.001 2.309-6.476 5.634-7.032 5.307-0.847 10.733-0.271 16.088-0.369 0.091-2.196 0.115-4.392 0.107-6.585-7.333 0.387-15.043-1.038-22.063 1.611zm52.714-1.294c-8.12-0.952-16.332-0.149-24.492-0.387-0.021 6.43-3e-3 12.854 0.078 19.274 2.625-0.849 5.251-1.739 7.909-2.532 0.042-3.272 0.028-6.527-0.071-9.789 4.869-0.029 9.874-0.757 14.639 0.451 1.838 0.298 2.051 2.25 2.687 3.641 2.541-0.891 5.111-1.717 7.672-2.574-0.703-4.246-4.129-7.633-8.422-8.084zm23.522-0.593c-3.954 0.072-7.912 0.064-11.864 0.047 0.051 2.544 0.063 5.074 0.072 7.617 4.263-1.482 8.553-2.889 12.848-4.268-0.35-1.128-0.706-2.268-1.056-3.396z" fill="#fff"/>
|
||||
<path d="m161.96 69.125c7.886-3.717 15.757-7.463 23.72-11.018 5.563 0.359 11.146 0.021 16.722 0.193 1.14-0.036 2.292-0.061 3.432-0.088-0.011-3.195-0.025-6.38-0.082-9.564 3.428-1.502 10.227-4.623 10.227-4.623l15.215 13.941 11.096 0.106-0.715-26.236 0.803-0.211 9.005 26.344 8.834-0.066 8.99-28.394-0.308 28.434 8.074-0.021-0.231-37.932-9.279 0.071 30.625-14.141s-37.593 14.279-56.404 21.385c-2.996 1.022-5.878 2.315-8.853 3.394-2.278 0.867-4.558 1.713-6.834 2.58-20.071 7.526-39.945 15.604-60.126 22.803-6.777-10.522-15.314-19.854-21.768-30.585zm72.116-17.961c-0.108 0.154-0.324 0.458-0.429 0.611-3.448-3.018-6.765-6.189-10.21-9.205 1.745-1.096 3.47-2.242 5.026-3.597 1.625-1.386 3.479-2.469 5.345-3.499 0.293 5.227 0.258 10.452 0.268 15.69zm23.942-9.67c-0.857 2.578-1.825 5.137-2.793 7.682-1.644-6.217-3.94-12.238-5.856-18.383-0.119-0.52-0.366-1.574-0.487-2.093 3.428-1.709 10.585-4.854 15.229-6.815-1.647 5.969-4.306 14.029-6.093 19.609z" fill="#ffb300"/>
|
||||
<g fill="#fff">
|
||||
<path d="m45.672 58.148h-18.526c-2.861 0-5.614-0.651-8.257-1.953-2.861-1.409-5.043-3.651-6.547-6.725-1.503-3.074-2.254-6.455-2.254-10.145 0-3.652 0.724-6.961 2.173-9.926 1.594-3.219 3.803-5.569 6.628-7.052 1.557-0.795 3.052-1.355 4.482-1.682 1.43-0.325 3.07-0.488 4.917-0.488h17.168v6.789h-15.886c-1.415 0-2.602 0.187-3.563 0.558-0.961 0.372-1.912 1.037-2.855 1.994s-1.597 1.887-1.959 2.791c-0.363 0.902-0.543 2.027-0.543 3.375h25.023v6.789h-25.025c0 1.24 0.164 2.325 0.491 3.256 0.327 0.93 0.919 1.887 1.776 2.871 0.856 0.985 1.749 1.732 2.677 2.242 0.929 0.512 2.03 0.767 3.306 0.767h16.774z"/>
|
||||
<path d="m76.499 49.519c0 2.397-0.771 4.449-2.312 6.154-1.541 1.706-3.49 2.56-5.846 2.56h-18.653v-5.113h15.326c1.087 0 2.001-0.272 2.744-0.817s1.115-1.327 1.115-2.345c0-2.362-1.595-3.543-4.783-3.543h-7.825c-1.666 0-3.278-0.79-4.836-2.369-1.559-1.58-2.336-3.287-2.336-5.119 0-2.585 0.579-4.667 1.738-6.248 1.34-1.794 3.313-2.692 5.922-2.692h17.928v5.364h-15.938c-0.614 0-1.147 0.289-1.599 0.868s-0.677 1.235-0.677 1.972c0 0.807 0.298 1.498 0.896 2.076 0.597 0.579 1.311 0.867 2.144 0.867h8.415c2.643 0 4.733 0.79 6.271 2.369 1.536 1.579 2.306 3.584 2.306 6.016z"/>
|
||||
<path d="m109.29 43.414c0 4.495-1.166 8.074-3.497 10.738s-5.395 3.996-9.188 3.996h-8.186v10.309h-7.627v-38.472h15.09c4.27 0 7.6 1.269 9.989 3.806 2.279 2.428 3.419 5.637 3.419 9.623zm-7.627 0.405c0-2.356-0.754-4.286-2.262-5.793-1.509-1.505-3.388-2.258-5.641-2.258h-5.341v16.429h5.886c2.179 0 3.951-0.771 5.313-2.313 1.363-1.54 2.045-3.562 2.045-6.065z"/>
|
||||
<path d="m145.1 43.967c0 4.896-1.557 8.65-4.669 11.261-2.86 2.394-6.751 3.591-11.673 3.591-4.923 0-8.742-1.087-11.456-3.264-3.15-2.502-4.724-6.401-4.724-11.696 0-4.424 1.701-7.906 5.104-10.446 3.04-2.283 6.786-3.427 11.238-3.427 4.887 0 8.805 1.225 11.754 3.673s4.426 5.884 4.426 10.308zm-8.382-0.065c0-2.285-0.716-4.197-2.146-5.738-1.432-1.54-3.379-2.312-5.841-2.312-2.246 0-4.103 0.79-5.57 2.366-1.467 1.577-2.2 3.563-2.2 5.955 0 2.756 0.743 4.949 2.228 6.581s3.405 2.448 5.76 2.448c2.679 0 4.673-0.852 5.977-2.557 1.193-1.557 1.792-3.805 1.792-6.743z"/>
|
||||
</g>
|
||||
</g>
|
||||
</switch>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
1299
client/modules/crm/css/vis.css
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="calendar-container no-window-scroll">
|
||||
{{{calendar}}}
|
||||
</div>
|
||||
32
client/modules/crm/res/templates/calendar/calendar.tpl
Normal file
@@ -0,0 +1,32 @@
|
||||
{{#if header}}
|
||||
<div class="row button-container">
|
||||
<div class="col-sm-4 col-xs-5">
|
||||
<div class="btn-group range-switch-group">
|
||||
<button class="btn btn-text btn-icon" data-action="prev"><span class="fas fa-chevron-left"></span></button>
|
||||
<button class="btn btn-text btn-icon" data-action="next"><span class="fas fa-chevron-right"></span></button>
|
||||
</div>
|
||||
<div class="btn-group range-switch-group">
|
||||
<button class="btn btn-text strong" data-action="today" title="{{todayLabel}}">
|
||||
<span class="hidden-sm hidden-xs">{{todayLabel}}</span><span class="visible-sm visible-xs">{{todayLabelShort}}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="btn btn-text{{#unless isCustomView}} hidden{{/unless}} btn-icon"
|
||||
data-action="editCustomView"
|
||||
title="{{translate 'Edit'}}"
|
||||
><span class="fas fa-pencil-alt fa-sm"></span></button>
|
||||
</div>
|
||||
|
||||
<div class="date-title col-sm-4 col-xs-7">
|
||||
<h4><span style="cursor: pointer;" data-action="refresh" title="{{translate 'Refresh'}}"></span></h4></div>
|
||||
|
||||
<div class="col-sm-4 col-xs-12">
|
||||
<div class="btn-group pull-right mode-buttons">
|
||||
{{{modeButtons}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="calendar"></div>
|
||||
20
client/modules/crm/res/templates/calendar/modals/edit.tpl
Normal file
@@ -0,0 +1,20 @@
|
||||
{{#if isNew}}
|
||||
<div class="scope-switcher radio-container">
|
||||
{{#each scopeList}}
|
||||
<div>
|
||||
<label class="radio-label">
|
||||
<input
|
||||
type="radio"
|
||||
name="scope"
|
||||
class="form-radio"
|
||||
{{#ifEqual this ../scope}} checked{{/ifEqual}}
|
||||
value="{{./this}}"
|
||||
>
|
||||
{{translate this category='scopeNames'}}
|
||||
</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="edit-container record no-side-margin">{{{edit}}}</div>
|
||||
53
client/modules/crm/res/templates/calendar/mode-buttons.tpl
Normal file
@@ -0,0 +1,53 @@
|
||||
{{#each visibleModeDataList}}
|
||||
<button class="btn btn-text strong{{#ifEqual mode ../mode}} active{{/ifEqual}}" data-action="mode" data-mode="{{mode}}" title="{{label}}"><span class="hidden-md hidden-sm hidden-xs">{{label}}</span><span class="visible-md visible-sm visible-xs">{{labelShort}}</span></button>
|
||||
{{/each}}
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-text dropdown-toggle" data-toggle="dropdown"><span class="fas fa-ellipsis-h"></span></button>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
{{#each hiddenModeDataList}}
|
||||
<li>
|
||||
<a
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="{{#ifEqual mode ../mode}} active{{/ifEqual}}"
|
||||
data-action="mode"
|
||||
data-mode="{{mode}}"
|
||||
>{{label}}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
{{#if hiddenModeDataList.length}}
|
||||
<li class="divider"></li>
|
||||
{{/if}}
|
||||
{{#each scopeFilterDataList}}
|
||||
<li>
|
||||
<a
|
||||
role="button"
|
||||
tabindex="0"
|
||||
data-action="toggleScopeFilter"
|
||||
data-name="{{scope}}"
|
||||
>
|
||||
<span class="fas fa-check filter-check-icon check-icon pull-right{{#if disabled}} hidden{{/if}}"></span>
|
||||
<div>{{translate scope category='scopeNamesPlural'}}</div>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
{{#if hasMoreItems}}
|
||||
<li class="divider"></li>
|
||||
{{/if}}
|
||||
{{#if isCustomViewAvailable}}
|
||||
<li>
|
||||
<a
|
||||
role="button"
|
||||
tabindex="0"
|
||||
data-action="createCustomView"
|
||||
>{{translate 'Create Shared View' scope='Calendar'}}</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if hasWorkingTimeCalendarLink}}
|
||||
<li>
|
||||
<a href="#WorkingTimeCalendar">{{translate 'WorkingTimeCalendar' category='scopeNamesPlural'}}</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</div>
|
||||
55
client/modules/crm/res/templates/calendar/timeline.tpl
Normal file
@@ -0,0 +1,55 @@
|
||||
<link href="{{basePath}}client/modules/crm/css/vis.css" rel="stylesheet">
|
||||
|
||||
{{#if header}}
|
||||
<div class="row button-container">
|
||||
<div class="col-sm-4 col-xs-12">
|
||||
<div class="btn-group">
|
||||
<button
|
||||
class="btn btn-text btn-icon"
|
||||
title="{{translate 'Refresh'}}"
|
||||
data-action="refresh"
|
||||
><span class="fas fa-sync-alt"></span></button>
|
||||
<button
|
||||
class="btn btn-text"
|
||||
data-action="today"
|
||||
>{{translate 'Today' scope='Calendar'}}</button>
|
||||
</div>{{#if calendarTypeSelectEnabled}}<div class="btn-group calendar-type-button-group">
|
||||
<div class="btn-group " role="group">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-text dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
><span class="calendar-type-label">{{calendarTypeLabel}}</span> <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
{{#each calendarTypeDataList}}
|
||||
<li>
|
||||
<a role="button" tabindex="0" data-action="toggleCalendarType" data-name="{{type}}">
|
||||
<span
|
||||
class="fas fa-check calendar-type-check-icon pull-right{{#if disabled}} hidden{{/if}}"
|
||||
></span> {{label}}
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-text{{#ifNotEqual calendarType 'shared'}} hidden{{/ifNotEqual}} btn-icon"
|
||||
data-action="showSharedCalendarOptions"
|
||||
title="{{translate 'Shared Mode Options' scope='Calendar'}}"
|
||||
><span class="fas fa-pencil-alt fa-sm"></span></button>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="date-title col-sm-4 hidden-xs">
|
||||
<h4><span style="cursor: pointer;" data-action="refresh" title="{{translate 'Refresh'}}"></span></h4></div>
|
||||
|
||||
<div class="col-sm-4 col-xs-12">
|
||||
<div class="btn-group pull-right mode-buttons">
|
||||
{{{modeButtons}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="timeline"></div>
|
||||
@@ -0,0 +1 @@
|
||||
{{{value}}}
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class="row">
|
||||
<div class="cell col-md-6">
|
||||
<div class="field" data-name="link">
|
||||
<select class="form-control" data-name="link">
|
||||
{{#each linkList}}
|
||||
<option value="{{./this}}">{{translate this category='links' scope='TargetList'}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
21
client/modules/crm/res/templates/campaign/unsubscribe.tpl
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="container content">
|
||||
<div class="block-center-md">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
{{#if isSubscribed}}
|
||||
<a
|
||||
class="btn btn-primary{{#if inProcess}} disabled{{/if}}"
|
||||
data-action="unsubscribe"
|
||||
>{{translate 'Unsubscribe' scope='Campaign'}}</a>
|
||||
{{else}}
|
||||
<a
|
||||
class="btn btn-default{{#if inProcess}} disabled{{/if}}"
|
||||
data-action="subscribe"
|
||||
>{{translate 'Subscribe again' scope='Campaign'}}</a>
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
{{#if accountIsInactive}}<del>{{/if}}<span title="{{value}}">{{value}}</span>{{#if accountIsInactive}}</del>{{/if}}
|
||||
9
client/modules/crm/res/templates/document/list.tpl
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="page-header">{{{header}}}</div>
|
||||
<div class="search-container">{{{search}}}</div>
|
||||
|
||||
<div class="row">
|
||||
{{#unless categoriesDisabled}}
|
||||
<div class="categories-container{{#unless categoriesDisabled}} col-md-3 col-sm-4{{else}} col-md-12{{/unless}}">{{{categories}}}</div>
|
||||
{{/unless}}
|
||||
<div class="list-container{{#unless categoriesDisabled}} col-md-9 col-sm-8{{else}} col-md-12{{/unless}}">{{{list}}}</div>
|
||||
</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
<div class="search-container">{{{search}}}</div>
|
||||
|
||||
<div class="row">
|
||||
{{#unless categoriesDisabled}}
|
||||
<div class="categories-container{{#unless categoriesDisabled}} col-md-3 col-sm-4{{else}} col-md-12{{/unless}}">{{{categories}}}</div>
|
||||
{{/unless}}
|
||||
<div class="list-container{{#unless categoriesDisabled}} col-md-9 col-sm-8{{else}} col-md-12{{/unless}}">{{{list}}}</div>
|
||||
</div>
|
||||
|
||||
{{#if createButton}}
|
||||
<div class="button-container">
|
||||
<button class="btn btn-default" data-action="create">{{translate 'Create'}}</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,36 @@
|
||||
<div class="container content">
|
||||
<div class="block-center-md">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h4 class="margin-bottom-2x">{{actionData.translatedEntityType}}: {{actionData.eventName}}</h4>
|
||||
{{#if dateStart}}
|
||||
<div class="margin-bottom-2x">
|
||||
{{#if dateStartChanged}}
|
||||
<div style="text-decoration: line-through;">{{sentDateStart}}</div>
|
||||
{{/if}}
|
||||
<div>{{dateStart}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div>
|
||||
<span class="label label-{{style}} label-md">{{actionData.translatedStatus}}</span>
|
||||
<div class="btn-group">
|
||||
{{#if actionDataList}}
|
||||
<a role="button" class="dropdown-toggle text-soft" data-toggle="dropdown">
|
||||
<span class="fas fa-ellipsis-h"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{{#each actionDataList}}
|
||||
<li>
|
||||
<a {{#if link}}href="{{link}}"{{/if}}>{{label}}
|
||||
{{#if active}}<span class="fas fa-check pull-right"></span>{{/if}}
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="page-header">{{{header}}}</div>
|
||||
<div class="search-container">{{{search}}}</div>
|
||||
|
||||
<div class="row">
|
||||
{{#unless categoriesDisabled}}
|
||||
<div class="categories-container{{#unless categoriesDisabled}} col-md-3 col-sm-4{{else}} col-md-12{{/unless}}">{{{categories}}}</div>
|
||||
{{/unless}}
|
||||
<div class="list-container{{#unless categoriesDisabled}} col-md-9 col-sm-8{{else}} col-md-12{{/unless}}">{{{list}}}</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<div class="search-container">{{{search}}}</div>
|
||||
|
||||
<div class="row">
|
||||
{{#unless categoriesDisabled}}
|
||||
<div class="categories-container{{#unless categoriesDisabled}} col-md-3 col-sm-4{{else}} col-md-12{{/unless}}">{{{categories}}}</div>
|
||||
{{/unless}}
|
||||
<div class="list-container{{#unless categoriesDisabled}} col-md-9 col-sm-8{{else}} col-md-12{{/unless}}">{{{list}}}</div>
|
||||
</div>
|
||||
|
||||
{{#if createButton}}
|
||||
<div class="button-container">
|
||||
<button class="btn btn-default" data-action="create">{{translate 'Create'}}</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
24
client/modules/crm/res/templates/lead/convert.tpl
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="header page-header">{{{header}}}</div>
|
||||
|
||||
{{#each scopeList}}
|
||||
<div class="record">
|
||||
<label style="user-select: none; cursor: pointer;" class="text-large">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="check-scope form-checkbox"
|
||||
data-scope="{{./this}}"
|
||||
>
|
||||
<span>{{translate this category='scopeNames'}}</span>
|
||||
</label>
|
||||
<div class="edit-container-{{toDom this}} hide">
|
||||
{{{var this ../this}}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
<div class="button-container margin-top">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary" data-action="convert">{{translate 'Convert' scope='Lead'}}</button>
|
||||
<button class="btn btn-default" data-action="cancel">{{translate 'Cancel'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,5 @@
|
||||
{{#if value}}
|
||||
{{{value}}}
|
||||
{{else}}
|
||||
<span class="none-value">{{translate 'None'}}</span>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="reminders-container"></div>
|
||||
<button
|
||||
data-action="addReminder"
|
||||
class="btn btn-default"
|
||||
type="button"
|
||||
><span class="fas fa-plus"></span></button>
|
||||
@@ -0,0 +1,39 @@
|
||||
{{#if closeButton~}}
|
||||
<a
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="pull-right close"
|
||||
data-action="close"
|
||||
aria-hidden="true"
|
||||
title="{{translate 'Close'}}"
|
||||
><span class="fas fa-times"></span></a>
|
||||
{{~/if~}}
|
||||
{{#if collapseButton~}}
|
||||
<a
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="pull-right text-muted"
|
||||
data-action="collapse"
|
||||
aria-hidden="true"
|
||||
title="{{translate 'Collapse'}}"
|
||||
><span class="fas fa-minus"></span></a>
|
||||
{{~/if}}
|
||||
<h4>{{header}}</h4>
|
||||
|
||||
|
||||
<div class="cell form-group">
|
||||
<div class="field">
|
||||
<a
|
||||
href="#{{notificationData.entityType}}/view/{{notificationData.id}}"
|
||||
data-action="close"
|
||||
>{{notificationData.name}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="cell form-group" data-name="{{dateField}}">
|
||||
<div class="field" data-name="{{dateField}}">
|
||||
{{{date}}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="list-container">
|
||||
{{{list}}}
|
||||
</div>
|
||||
48
client/modules/crm/src/acl-portal/account.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import AclPortal from 'acl-portal';
|
||||
|
||||
class AccountAclPortal extends AclPortal {
|
||||
|
||||
checkInAccount(model) {
|
||||
const accountIdList = this.getUser().getLinkMultipleIdList('accounts');
|
||||
|
||||
if (!accountIdList.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (~accountIdList.indexOf(model.id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default AccountAclPortal;
|
||||
48
client/modules/crm/src/acl-portal/contact.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import AclPortal from 'acl-portal';
|
||||
|
||||
class ContactAclPortal extends AclPortal {
|
||||
|
||||
checkIsOwnContact(model) {
|
||||
const contactId = this.getUser().get('contactId');
|
||||
|
||||
if (!contactId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contactId === model.id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default ContactAclPortal;
|
||||
49
client/modules/crm/src/acl-portal/document.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import AclPortal from 'acl-portal';
|
||||
|
||||
class DocumentAclPortal extends AclPortal {
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
checkModelEdit(model, data, precise) {
|
||||
let result = this.checkModel(model, data, 'delete', precise);
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data.edit === 'account') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default DocumentAclPortal;
|
||||
33
client/modules/crm/src/acl/call.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import MeetingAcl from 'modules/crm/acl/meeting';
|
||||
|
||||
class CallAcl extends MeetingAcl {}
|
||||
|
||||
export default CallAcl;
|
||||
50
client/modules/crm/src/acl/campaign-tracking-url.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Acl from 'acl';
|
||||
|
||||
class CampaignTrackingUrlAcl extends Acl {
|
||||
|
||||
checkIsOwner(model) {
|
||||
if (model.has('campaignId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
checkInTeam(model) {
|
||||
if (model.has('campaignId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default CampaignTrackingUrlAcl;
|
||||
58
client/modules/crm/src/acl/mass-email.js
Normal file
@@ -0,0 +1,58 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Acl from 'acl';
|
||||
|
||||
class MassEmailAcl extends Acl {
|
||||
|
||||
checkScope(data, action, precise, entityAccessData) {
|
||||
if (action === 'create') {
|
||||
return super.checkScope(data, 'edit', precise, entityAccessData);
|
||||
}
|
||||
|
||||
return super.checkScope(data, action, precise, entityAccessData);
|
||||
}
|
||||
|
||||
checkIsOwner(model) {
|
||||
if (model.has('campaignId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.checkIsOwner(model);
|
||||
}
|
||||
|
||||
checkInTeam(model) {
|
||||
if (model.has('campaignId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.checkInTeam(model);
|
||||
}
|
||||
}
|
||||
|
||||
export default MassEmailAcl;
|
||||
74
client/modules/crm/src/acl/meeting.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Acl from 'acl';
|
||||
|
||||
class MeetingAcl extends Acl {
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
checkModelRead(model, data, precise) {
|
||||
return this._checkModelCustom('read', model, data, precise);
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
checkModelStream(model, data, precise) {
|
||||
return this._checkModelCustom('stream', model, data, precise);
|
||||
}
|
||||
|
||||
_checkModelCustom(action, model, data, precise) {
|
||||
let result = this.checkModel(model, data, action, precise);
|
||||
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let d = data || {};
|
||||
|
||||
if (d[action] === 'no') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (model.has('usersIds')) {
|
||||
if (~(model.get('usersIds') || []).indexOf(this.getUser().id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (precise) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export default MeetingAcl;
|
||||
|
||||
73
client/modules/crm/src/controllers/activities.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Controller from 'controller';
|
||||
|
||||
export default class ActivitiesController extends Controller {
|
||||
|
||||
checkAccess(action) {
|
||||
return this.getAcl().check('Activities');
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionActivities(options) {
|
||||
this.processList('activities', options.entityType, options.id, options.targetEntityType);
|
||||
}
|
||||
|
||||
actionHistory(options) {
|
||||
this.processList('history', options.entityType, options.id, options.targetEntityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {'activities'|'history'} type
|
||||
* @param {string} entityType
|
||||
* @param {string} id
|
||||
* @param {string} targetEntityType
|
||||
*/
|
||||
async processList(type, entityType, id, targetEntityType) {
|
||||
const viewName = 'modules/crm/views/activities/list';
|
||||
|
||||
const model = await this.modelFactory.create(entityType)
|
||||
|
||||
model.id = id;
|
||||
|
||||
await model.fetch({main: true});
|
||||
|
||||
const collection = await this.collectionFactory.create(targetEntityType);
|
||||
collection.url = `Activities/${model.entityType}/${id}/${type}/list/${targetEntityType}`;
|
||||
|
||||
this.main(viewName, {
|
||||
scope: entityType,
|
||||
model: model,
|
||||
collection: collection,
|
||||
link: `${type}_${targetEntityType}`,
|
||||
type: type,
|
||||
});
|
||||
}
|
||||
}
|
||||
58
client/modules/crm/src/controllers/calendar.js
Normal file
@@ -0,0 +1,58 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Controller from 'controller';
|
||||
|
||||
class CalendarController extends Controller {
|
||||
|
||||
checkAccess() {
|
||||
if (this.getAcl().check('Calendar')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionShow(options) {
|
||||
this.actionIndex(options);
|
||||
}
|
||||
|
||||
actionIndex(options) {
|
||||
this.handleCheckAccess('');
|
||||
|
||||
this.main('crm:views/calendar/calendar-page', {
|
||||
date: options.date,
|
||||
mode: options.mode,
|
||||
userId: options.userId,
|
||||
userName: options.userName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default CalendarController;
|
||||
47
client/modules/crm/src/controllers/event-confirmation.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Controller from 'controller';
|
||||
|
||||
class EventConfirmationController extends Controller {
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionConfirmEvent(actionData) {
|
||||
const viewName = this.getMetadata().get(['clientDefs', 'EventConfirmation', 'confirmationView']) ||
|
||||
'crm:views/event-confirmation/confirmation';
|
||||
|
||||
this.entire(viewName, {
|
||||
actionData: actionData,
|
||||
}, view => {
|
||||
view.render();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default EventConfirmationController;
|
||||
39
client/modules/crm/src/controllers/lead.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import RecordController from 'controllers/record';
|
||||
|
||||
class LeadController extends RecordController {
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionConvert(options) {
|
||||
this.main('crm:views/lead/convert', {id: options.id});
|
||||
}
|
||||
}
|
||||
|
||||
export default LeadController;
|
||||
44
client/modules/crm/src/controllers/task.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import RecordController from 'controllers/record';
|
||||
|
||||
export default class TaskController extends RecordController {
|
||||
|
||||
actionCreate(options) {
|
||||
const attributes = {...options.attributes};
|
||||
|
||||
if (options.emailId) {
|
||||
attributes.emailId = options.emailId;
|
||||
|
||||
options.attributes = attributes;
|
||||
}
|
||||
|
||||
super.actionCreate(options);
|
||||
}
|
||||
}
|
||||
46
client/modules/crm/src/controllers/tracking-url.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Controller from 'controller';
|
||||
|
||||
class TrackingUrlController extends Controller {
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionDisplayMessage(data) {
|
||||
const viewName = data.view || 'crm:views/campaign/tracking-url';
|
||||
|
||||
this.entire(viewName, {
|
||||
message: data.message,
|
||||
template: data.template,
|
||||
}, view => {
|
||||
view.render();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default TrackingUrlController
|
||||
46
client/modules/crm/src/controllers/unsubscribe.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Controller from 'controller';
|
||||
|
||||
class UnsubscribeController extends Controller {
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
actionUnsubscribe(data) {
|
||||
const viewName = data.view || 'crm:views/campaign/unsubscribe';
|
||||
|
||||
this.entire(viewName, {
|
||||
actionData: data.actionData,
|
||||
template: data.template,
|
||||
}, view => {
|
||||
view.render();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default UnsubscribeController;
|
||||
@@ -0,0 +1,40 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import CreateRelated from 'handlers/create-related';
|
||||
|
||||
class MassEmailsCreateHandler extends CreateRelated {
|
||||
|
||||
getAttributes(model) {
|
||||
return Promise.resolve({
|
||||
name: model.get('name') + ' ' + this.viewHelper.dateTime.getToday(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default MassEmailsCreateHandler;
|
||||
91
client/modules/crm/src/handlers/case/detail-actions.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import ActionHandler from 'action-handler';
|
||||
|
||||
class CaseDetailActionHandler extends ActionHandler {
|
||||
|
||||
close() {
|
||||
const model = this.view.model;
|
||||
|
||||
model.save({status: 'Closed'}, {patch: true})
|
||||
.then(() => {
|
||||
Espo.Ui.success(this.view.translate('Closed', 'labels', 'Case'));
|
||||
});
|
||||
}
|
||||
|
||||
reject() {
|
||||
const model = this.view.model;
|
||||
|
||||
model.save({status: 'Rejected'}, {patch: true})
|
||||
.then(() => {
|
||||
Espo.Ui.success(this.view.translate('Rejected', 'labels', 'Case'));
|
||||
});
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
isCloseAvailable() {
|
||||
return this.isStatusAvailable('Closed');
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
isRejectAvailable() {
|
||||
return this.isStatusAvailable('Rejected');
|
||||
}
|
||||
|
||||
isStatusAvailable(status) {
|
||||
const model = this.view.model;
|
||||
const acl = this.view.getAcl();
|
||||
const metadata = this.view.getMetadata();
|
||||
|
||||
/** @type {string[]} */
|
||||
const notActualStatuses = metadata.get('entityDefs.Case.fields.status.notActualOptions') || [];
|
||||
|
||||
if (notActualStatuses.includes(model.get('status'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!acl.check(model, 'edit')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!acl.checkField(model.entityType, 'status', 'edit')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const statusList = metadata.get(['entityDefs', 'Case', 'fields', 'status', 'options']) || [];
|
||||
|
||||
if (!statusList.includes(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export default CaseDetailActionHandler;
|
||||
93
client/modules/crm/src/handlers/event/reminders-handler.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import {Events} from 'bullbone';
|
||||
|
||||
/**
|
||||
* @mixes Bull.Events
|
||||
*/
|
||||
class RemindersHandler {
|
||||
|
||||
/**
|
||||
* @param {import('views/record/detail').default} view
|
||||
*/
|
||||
constructor(view) {
|
||||
this.view = view;
|
||||
/** @type {import('model').default} */
|
||||
this.model = view.model;
|
||||
/** @type {import('models/user').default} */
|
||||
this.user = this.view.getUser();
|
||||
|
||||
this.ignoreStatusList = [
|
||||
...(this.view.getMetadata().get(['scopes', this.view.entityType, 'completedStatusList']) || []),
|
||||
...(this.view.getMetadata().get(['scopes', this.view.entityType, 'canceledStatusList']) || []),
|
||||
];
|
||||
}
|
||||
|
||||
process() {
|
||||
this.control();
|
||||
|
||||
this.listenTo(this.model, 'change', () => {
|
||||
if (
|
||||
!this.model.hasChanged('assignedUserId') &&
|
||||
!this.model.hasChanged('usersIds') &&
|
||||
!this.model.hasChanged('assignedUsersIds') &&
|
||||
!this.model.hasChanged('status')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.control();
|
||||
});
|
||||
}
|
||||
|
||||
control() {
|
||||
const usersIds = /** @type {string[]} */this.model.get('usersIds') || [];
|
||||
const assignedUsersIds = /** @type {string[]} */this.model.get('assignedUsersIds') || [];
|
||||
|
||||
if (
|
||||
!this.ignoreStatusList.includes(this.model.get('status')) &&
|
||||
(
|
||||
this.model.get('assignedUserId') === this.user.id ||
|
||||
usersIds.includes(this.user.id) ||
|
||||
assignedUsersIds.includes(this.user.id)
|
||||
)
|
||||
) {
|
||||
this.view.showField('reminders');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.view.hideField('reminders');
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(RemindersHandler.prototype, Events);
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default RemindersHandler;
|
||||
136
client/modules/crm/src/handlers/knowledge-base-article/move.js
Normal file
@@ -0,0 +1,136 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import RowActionHandler from 'handlers/row-action';
|
||||
|
||||
class MoveActionHandler extends RowActionHandler {
|
||||
|
||||
isAvailable(model, action) {
|
||||
return model.collection &&
|
||||
model.collection.orderBy === 'order' &&
|
||||
model.collection.order === 'asc';
|
||||
}
|
||||
|
||||
process(model, action) {
|
||||
if (action === 'moveToTop') {
|
||||
this.moveToTop(model);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === 'moveToBottom') {
|
||||
this.moveToBottom(model);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === 'moveUp') {
|
||||
this.moveUp(model);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === 'moveDown') {
|
||||
this.moveDown(model);
|
||||
}
|
||||
}
|
||||
|
||||
moveToTop(model) {
|
||||
const index = this.collection.indexOf(model);
|
||||
|
||||
if (index === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Espo.Ui.notifyWait();
|
||||
|
||||
Espo.Ajax.postRequest('KnowledgeBaseArticle/action/moveToTop', {
|
||||
id: model.id,
|
||||
whereGroup: this.collection.getWhere(),
|
||||
}).then(() => {
|
||||
this.collection.fetch()
|
||||
.then(() => Espo.Ui.notify(false));
|
||||
});
|
||||
}
|
||||
|
||||
moveUp(model) {
|
||||
const index = this.collection.indexOf(model);
|
||||
|
||||
if (index === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Espo.Ui.notifyWait();
|
||||
|
||||
Espo.Ajax.postRequest('KnowledgeBaseArticle/action/moveUp', {
|
||||
id: model.id,
|
||||
whereGroup: this.collection.getWhere(),
|
||||
}).then(() => {
|
||||
this.collection.fetch()
|
||||
.then(() => Espo.Ui.notify(false));
|
||||
});
|
||||
}
|
||||
|
||||
moveDown(model) {
|
||||
const index = this.collection.indexOf(model);
|
||||
|
||||
if ((index === this.collection.length - 1) && (this.collection.length === this.collection.total)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Espo.Ui.notifyWait();
|
||||
|
||||
Espo.Ajax.postRequest('KnowledgeBaseArticle/action/moveDown', {
|
||||
id: model.id,
|
||||
whereGroup: this.collection.getWhere(),
|
||||
}).then(() => {
|
||||
this.collection.fetch()
|
||||
.then(() => Espo.Ui.notify(false));
|
||||
});
|
||||
}
|
||||
|
||||
moveToBottom(model) {
|
||||
const index = this.collection.indexOf(model);
|
||||
|
||||
if ((index === this.collection.length - 1) && (this.collection.length === this.collection.total)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Espo.Ui.notifyWait();
|
||||
|
||||
Espo.Ajax.postRequest('KnowledgeBaseArticle/action/moveToBottom', {
|
||||
id: model.id,
|
||||
whereGroup: this.collection.getWhere(),
|
||||
}).then(() => {
|
||||
this.collection.fetch()
|
||||
.then(() => Espo.Ui.notify(false));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default MoveActionHandler;
|
||||
@@ -0,0 +1,149 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import RowActionHandler from 'handlers/row-action';
|
||||
|
||||
class SendInEmailHandler extends RowActionHandler {
|
||||
|
||||
isAvailable(model, action) {
|
||||
return this.view.getAcl().checkScope('Email', 'create');
|
||||
}
|
||||
|
||||
process(model, action) {
|
||||
const parentModel = this.view.getParentView().model;
|
||||
const modelFactory = this.view.getModelFactory();
|
||||
const collectionFactory = this.view.getCollectionFactory();
|
||||
|
||||
Espo.Ui.notifyWait();
|
||||
|
||||
model.fetch()
|
||||
.then(() => {
|
||||
return new Promise(resolve => {
|
||||
if (
|
||||
parentModel.get('contactsIds') &&
|
||||
parentModel.get('contactsIds').length
|
||||
) {
|
||||
collectionFactory.create('Contact', contactList => {
|
||||
const contactListFinal = [];
|
||||
contactList.url = 'Case/' + parentModel.id + '/contacts';
|
||||
|
||||
contactList.fetch().then(() => {
|
||||
contactList.forEach(contact => {
|
||||
if (contact.id === parentModel.get('contactId')) {
|
||||
contactListFinal.unshift(contact);
|
||||
} else {
|
||||
contactListFinal.push(contact);
|
||||
}
|
||||
});
|
||||
|
||||
resolve(contactListFinal);
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentModel.get('accountId')) {
|
||||
modelFactory.create('Account', account => {
|
||||
account.id = parentModel.get('accountId');
|
||||
|
||||
account.fetch()
|
||||
.then(() => resolve([account]));
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentModel.get('leadId')) {
|
||||
modelFactory.create('Lead', lead => {
|
||||
lead.id = parentModel.get('leadId');
|
||||
|
||||
lead.fetch()
|
||||
.then(() => resolve([lead]));
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
resolve([]);
|
||||
});
|
||||
})
|
||||
.then(list => {
|
||||
const attributes = {
|
||||
parentType: 'Case',
|
||||
parentId: parentModel.id,
|
||||
parentName: parentModel.get('name'),
|
||||
name: '[#' + parentModel.get('number') + ']',
|
||||
};
|
||||
|
||||
attributes.to = '';
|
||||
attributes.cc = '';
|
||||
attributes.nameHash = {};
|
||||
|
||||
list.forEach((model, i) => {
|
||||
if (model.get('emailAddress')) {
|
||||
if (i === 0) {
|
||||
attributes.to += model.get('emailAddress') + ';';
|
||||
} else {
|
||||
attributes.cc += model.get('emailAddress') + ';';
|
||||
}
|
||||
|
||||
attributes.nameHash[model.get('emailAddress')] = model.get('name');
|
||||
}
|
||||
});
|
||||
|
||||
Espo.loader.require('crm:knowledge-base-helper', Helper => {
|
||||
const helper = new Helper(this.view.getLanguage());
|
||||
|
||||
helper.getAttributesForEmail(model, attributes, attributes => {
|
||||
const viewName = this.view.getMetadata().get('clientDefs.Email.modalViews.compose') ||
|
||||
'views/modals/compose-email';
|
||||
|
||||
this.view.createView('composeEmail', viewName, {
|
||||
attributes: attributes,
|
||||
selectTemplateDisabled: true,
|
||||
signatureDisabled: true,
|
||||
}, view => {
|
||||
Espo.Ui.notify(false);
|
||||
|
||||
view.render();
|
||||
|
||||
this.view.listenToOnce(view, 'after:send', () => {
|
||||
parentModel.trigger('after:relate');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
Espo.Ui.notify(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default SendInEmailHandler;
|
||||
72
client/modules/crm/src/handlers/meeting/external-service.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import {inject} from 'di';
|
||||
import AppParams from 'app-params';
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default class MeetingExternalServiceHandler{
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {AppParams}
|
||||
*/
|
||||
@inject(AppParams)
|
||||
appParams
|
||||
|
||||
/**
|
||||
* @param {import('views/record/detail').default} view
|
||||
*/
|
||||
constructor(view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
process() {
|
||||
this.controlField();
|
||||
this.view.listenTo(this.view.model, 'change:externalService', () => this.controlField());
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
controlField() {
|
||||
const model = this.view.model;
|
||||
|
||||
if (model.attributes.externalService) {
|
||||
this.view.showField('externalService');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const list = this.appParams.get('meetingServices') ?? [];
|
||||
|
||||
if (!list.length) {
|
||||
this.view.hideField('externalService');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import CreateRelated from 'handlers/create-related';
|
||||
|
||||
class ContactsCreateHandler extends CreateRelated {
|
||||
|
||||
getAttributes(model) {
|
||||
const attributes = {};
|
||||
|
||||
if (model.get('accountId')) {
|
||||
attributes['accountsIds'] = [model.get('accountId')]
|
||||
}
|
||||
|
||||
return Promise.resolve(attributes);
|
||||
}
|
||||
}
|
||||
|
||||
export default ContactsCreateHandler;
|
||||
@@ -0,0 +1,56 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import DefaultsPreparator from 'handlers/model/defaults-preparator';
|
||||
import Metadata from 'metadata';
|
||||
import {inject} from 'di';
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default class extends DefaultsPreparator {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Metadata}
|
||||
*/
|
||||
@inject(Metadata)
|
||||
metadata
|
||||
|
||||
prepare(model) {
|
||||
const probabilityMap = this.metadata.get('entityDefs.Opportunity.fields.stage.probabilityMap') || {};
|
||||
const stage = model.attributes.stage;
|
||||
|
||||
const attributes = {};
|
||||
|
||||
if (stage in probabilityMap) {
|
||||
attributes.probability = probabilityMap[stage];
|
||||
}
|
||||
|
||||
return Promise.resolve(attributes);
|
||||
}
|
||||
}
|
||||
|
||||
89
client/modules/crm/src/handlers/task/detail-actions.js
Normal file
@@ -0,0 +1,89 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import ActionHandler from 'action-handler';
|
||||
import {inject} from 'di';
|
||||
import Metadata from 'metadata';
|
||||
import Ui from 'ui';
|
||||
|
||||
class DetailActions extends ActionHandler {
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
* @private
|
||||
*/
|
||||
historyStatusList
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|null}
|
||||
*/
|
||||
completedStatusValue
|
||||
|
||||
@inject(Metadata)
|
||||
metadata
|
||||
|
||||
constructor(view) {
|
||||
super(view);
|
||||
|
||||
/** @var string[]*/
|
||||
const completedStatusList = this.metadata.get(`scopes.Task.completedStatusList`, []);
|
||||
|
||||
this.historyStatusList = [
|
||||
...completedStatusList,
|
||||
...this.metadata.get(`scopes.Task.canceledStatusList`, []),
|
||||
];
|
||||
|
||||
this.completedStatusValue = completedStatusList[0] ?? null;
|
||||
}
|
||||
|
||||
async complete() {
|
||||
const model = this.view.model;
|
||||
|
||||
Ui.notifyWait();
|
||||
|
||||
await model.save({status: this.completedStatusValue}, {patch: true});
|
||||
|
||||
// Needed for calendar update.
|
||||
this.view.trigger('after:save', model);
|
||||
|
||||
Ui.success(this.view.getLanguage().translateOption('Completed', 'status', 'Task'));
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
isCompleteAvailable() {
|
||||
const status = this.view.model.attributes.status;
|
||||
|
||||
return !this.historyStatusList.includes(status);
|
||||
}
|
||||
}
|
||||
|
||||
export default DetailActions;
|
||||
90
client/modules/crm/src/handlers/task/menu.js
Normal file
@@ -0,0 +1,90 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import ActionHandler from 'action-handler';
|
||||
import {inject} from 'di';
|
||||
import Metadata from 'metadata';
|
||||
import Ui from 'ui';
|
||||
|
||||
export default class TaskMenuHandler extends ActionHandler {
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
* @private
|
||||
*/
|
||||
historyStatusList
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|null}
|
||||
*/
|
||||
completedStatusValue
|
||||
|
||||
@inject(Metadata)
|
||||
metadata
|
||||
|
||||
constructor(view) {
|
||||
super(view);
|
||||
|
||||
/** @var string[]*/
|
||||
const completedStatusList = this.metadata.get(`scopes.Task.completedStatusList`, []);
|
||||
|
||||
this.historyStatusList = [
|
||||
...completedStatusList,
|
||||
...this.metadata.get(`scopes.Task.canceledStatusList`, []),
|
||||
];
|
||||
|
||||
this.completedStatusValue = completedStatusList[0] ?? null;
|
||||
}
|
||||
|
||||
async complete() {
|
||||
const model = this.view.model;
|
||||
|
||||
Ui.notifyWait();
|
||||
|
||||
await model.save({status: this.completedStatusValue}, {patch: true});
|
||||
|
||||
Ui.success(this.view.getLanguage().translateOption('Completed', 'status', 'Task'));
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
isCompleteAvailable() {
|
||||
const status = this.view.model.attributes.status;
|
||||
|
||||
const view = /** @type {import('views/detail').default} */this.view;
|
||||
|
||||
if (view.getRecordView().isEditMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !this.historyStatusList.includes(status);
|
||||
}
|
||||
}
|
||||
97
client/modules/crm/src/handlers/task/reminders-handler.js
Normal file
@@ -0,0 +1,97 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import {Events} from 'bullbone';
|
||||
|
||||
/**
|
||||
* @mixes Bull.Events
|
||||
*/
|
||||
class RemindersHandler {
|
||||
|
||||
/**
|
||||
* @param {import('views/record/detail').default} view
|
||||
*/
|
||||
constructor(view) {
|
||||
this.view = view;
|
||||
this.model = view.model;
|
||||
this.user = this.view.getUser();
|
||||
|
||||
this.ignoreStatusList = [
|
||||
...(this.view.getMetadata().get(['scopes', this.view.entityType, 'completedStatusList']) || []),
|
||||
...(this.view.getMetadata().get(['scopes', this.view.entityType, 'canceledStatusList']) || []),
|
||||
];
|
||||
}
|
||||
|
||||
process() {
|
||||
this.control();
|
||||
|
||||
this.listenTo(this.model, 'change', () => {
|
||||
if (
|
||||
!this.model.hasChanged('assignedUserId') &&
|
||||
!this.model.hasChanged('assignedUsersIds') &&
|
||||
!this.model.hasChanged('dateEnd') &&
|
||||
!this.model.hasChanged('dateEndDate') &&
|
||||
!this.model.hasChanged('status')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.control();
|
||||
});
|
||||
}
|
||||
|
||||
control() {
|
||||
if (!this.model.attributes.dateEnd && !this.model.attributes.dateEndDate) {
|
||||
this.view.hideField('reminders');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @type {string[]} */
|
||||
const assignedUsersIds = this.model.attributes.assignedUsersIds || [];
|
||||
|
||||
if (
|
||||
!this.ignoreStatusList.includes(this.model.attributes.status) &&
|
||||
(
|
||||
this.model.attributes.assignedUserId === this.user.id ||
|
||||
assignedUsersIds.includes(this.user.id)
|
||||
)
|
||||
) {
|
||||
this.view.showField('reminders');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.view.hideField('reminders');
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(RemindersHandler.prototype, Events);
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default RemindersHandler;
|
||||
70
client/modules/crm/src/knowledge-base-helper.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import Ajax from 'ajax';
|
||||
|
||||
/**
|
||||
* @todo Move to modules/crm/helpers.
|
||||
*/
|
||||
class KnowledgeBaseHelper {
|
||||
|
||||
/**
|
||||
* @param {module:language} language
|
||||
*/
|
||||
constructor(language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
getAttributesForEmail(model, attributes, callback) {
|
||||
attributes = attributes || {};
|
||||
attributes.body = model.get('body');
|
||||
|
||||
if (attributes.name) {
|
||||
attributes.name = attributes.name + ' ';
|
||||
} else {
|
||||
attributes.name = '';
|
||||
}
|
||||
|
||||
attributes.name += this.language.translate('KnowledgeBaseArticle', 'scopeNames') + ': ' +
|
||||
model.get('name');
|
||||
|
||||
Ajax.postRequest('KnowledgeBaseArticle/action/getCopiedAttachments', {
|
||||
id: model.id,
|
||||
parentType: 'Email',
|
||||
field : 'attachments',
|
||||
}).then(data => {
|
||||
attributes.attachmentsIds = data.ids;
|
||||
attributes.attachmentsNames = data.names;
|
||||
attributes.isHtml = true;
|
||||
|
||||
callback(attributes);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default KnowledgeBaseHelper;
|
||||
@@ -0,0 +1,212 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import _ from 'underscore';
|
||||
import {Events} from 'bullbone';
|
||||
|
||||
const Handler = function (view) {
|
||||
this.view = view;
|
||||
};
|
||||
|
||||
_.extend(Handler.prototype, {
|
||||
|
||||
process: function () {
|
||||
this.listenTo(this.view, 'after:render', () => this.initDragDrop());
|
||||
this.listenTo(this.view, 'remove', () => this.disable());
|
||||
},
|
||||
|
||||
disable: function () {
|
||||
const $el = this.view.$el.parent();
|
||||
/** @type {Element} */
|
||||
const el = $el.get(0);
|
||||
|
||||
$el.off('drop');
|
||||
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.onDragoverBind) {
|
||||
return;
|
||||
}
|
||||
|
||||
el.removeEventListener('dragover', this.onDragoverBind);
|
||||
el.removeEventListener('dragenter', this.onDragenterBind);
|
||||
el.removeEventListener('dragleave', this.onDragleaveBind);
|
||||
},
|
||||
|
||||
initDragDrop: function () {
|
||||
this.disable();
|
||||
|
||||
const $el = this.view.$el.parent();
|
||||
const el = $el.get(0);
|
||||
|
||||
$el.on('drop', e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
e = e.originalEvent;
|
||||
|
||||
if (
|
||||
e.dataTransfer &&
|
||||
e.dataTransfer.files &&
|
||||
e.dataTransfer.files.length === 1 &&
|
||||
this.dropEntered
|
||||
) {
|
||||
this.removeDrop();
|
||||
|
||||
this.create(e.dataTransfer.files[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeDrop($el);
|
||||
});
|
||||
|
||||
|
||||
this.dropEntered = false;
|
||||
|
||||
this.onDragoverBind = this.onDragover.bind(this);
|
||||
this.onDragenterBind = this.onDragenter.bind(this);
|
||||
this.onDragleaveBind = this.onDragleave.bind(this);
|
||||
|
||||
el.addEventListener('dragover', this.onDragoverBind);
|
||||
el.addEventListener('dragenter', this.onDragenterBind);
|
||||
el.addEventListener('dragleave', this.onDragleaveBind);
|
||||
},
|
||||
|
||||
renderDrop: function () {
|
||||
this.dropEntered = true;
|
||||
|
||||
const $backdrop =
|
||||
$('<div class="dd-backdrop">')
|
||||
.css('pointer-events', 'none')
|
||||
.append('<span class="fas fa-paperclip"></span>')
|
||||
.append(' ')
|
||||
.append(
|
||||
$('<span>')
|
||||
.text(this.view.getLanguage().translate('Create Document', 'labels', 'Document'))
|
||||
);
|
||||
|
||||
this.view.$el.append($backdrop);
|
||||
},
|
||||
|
||||
removeDrop: function () {
|
||||
this.view.$el.find('> .dd-backdrop').remove();
|
||||
|
||||
this.dropEntered = false;
|
||||
},
|
||||
|
||||
create: function (file) {
|
||||
this.view
|
||||
.actionQuickCreate()
|
||||
.then(view => {
|
||||
const fileView = view.getRecordView().getFieldView('file');
|
||||
|
||||
if (!fileView) {
|
||||
const msg = "No 'file' field on the layout.";
|
||||
|
||||
Espo.Ui.error(msg);
|
||||
console.error(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileView.isRendered()) {
|
||||
fileView.uploadFile(file);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.listenToOnce(fileView, 'after:render', () => {
|
||||
fileView.uploadFile(file);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
onDragover: function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
onDragenter: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!e.dataTransfer.types || !e.dataTransfer.types.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!~e.dataTransfer.types.indexOf('Files')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.dropEntered) {
|
||||
this.renderDrop();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
onDragleave: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.dropEntered) {
|
||||
return;
|
||||
}
|
||||
|
||||
let fromElement = e.fromElement || e.relatedTarget;
|
||||
|
||||
if (
|
||||
fromElement &&
|
||||
$.contains(this.view.$el.parent().get(0), fromElement)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
fromElement &&
|
||||
fromElement.parentNode &&
|
||||
fromElement.parentNode.toString() === '[object ShadowRoot]'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeDrop();
|
||||
},
|
||||
});
|
||||
|
||||
Object.assign(Handler.prototype, Events);
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default Handler;
|
||||
32
client/modules/crm/src/views/account/detail.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import DetailView from 'views/detail';
|
||||
|
||||
/** Left for bc. */
|
||||
export default class extends DetailView {}
|
||||
135
client/modules/crm/src/views/account/fields/shipping-address.js
Normal file
@@ -0,0 +1,135 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import AddressFieldView from 'views/fields/address';
|
||||
|
||||
export default class extends AddressFieldView {
|
||||
|
||||
copyFrom = 'billingAddress'
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.addActionHandler('copyFromBilling', () => this.copy());
|
||||
|
||||
this.attributePartList = this.getMetadata().get(['fields', 'address', 'actualFields']) || [];
|
||||
|
||||
this.allAddressAttributeList = [];
|
||||
|
||||
this.attributePartList.forEach(part => {
|
||||
this.allAddressAttributeList.push(this.copyFrom + Espo.Utils.upperCaseFirst(part));
|
||||
this.allAddressAttributeList.push(this.name + Espo.Utils.upperCaseFirst(part));
|
||||
});
|
||||
|
||||
this.listenTo(this.model, 'change', () => {
|
||||
let isChanged = false;
|
||||
|
||||
for (const attribute of this.allAddressAttributeList) {
|
||||
if (this.model.hasChanged(attribute)) {
|
||||
isChanged = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isEditMode() || !this.isRendered() || !this.copyButtonElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.toShowCopyButton()) {
|
||||
this.copyButtonElement.classList.remove('hidden');
|
||||
} else {
|
||||
this.copyButtonElement.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
afterRender() {
|
||||
super.afterRender();
|
||||
|
||||
if (this.mode === this.MODE_EDIT && this.element) {
|
||||
const label = this.translate('Copy Billing', 'labels', 'Account');
|
||||
|
||||
const button = this.copyButtonElement = document.createElement('button');
|
||||
|
||||
button.classList.add('btn', 'btn-default', 'btn-sm', 'action');
|
||||
button.textContent = label;
|
||||
button.setAttribute('data-action', 'copyFromBilling')
|
||||
|
||||
if (!this.toShowCopyButton()) {
|
||||
button.classList.add('hidden');
|
||||
}
|
||||
|
||||
this.element.append(button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
copy() {
|
||||
const fieldFrom = this.copyFrom;
|
||||
|
||||
Object.keys(this.getMetadata().get('fields.address.fields') || {})
|
||||
.forEach(attr => {
|
||||
const destField = this.name + Espo.Utils.upperCaseFirst(attr);
|
||||
const sourceField = fieldFrom + Espo.Utils.upperCaseFirst(attr);
|
||||
|
||||
this.model.set(destField, this.model.get(sourceField));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {boolean}
|
||||
*/
|
||||
toShowCopyButton() {
|
||||
let billingIsNotEmpty = false;
|
||||
let shippingIsNotEmpty = false;
|
||||
|
||||
this.attributePartList.forEach(part => {
|
||||
const attribute1 = this.copyFrom + Espo.Utils.upperCaseFirst(part);
|
||||
|
||||
if (this.model.get(attribute1)) {
|
||||
billingIsNotEmpty = true;
|
||||
}
|
||||
|
||||
const attribute2 = this.name + Espo.Utils.upperCaseFirst(part);
|
||||
|
||||
if (this.model.get(attribute2)) {
|
||||
shippingIsNotEmpty = true;
|
||||
}
|
||||
});
|
||||
|
||||
return billingIsNotEmpty && !shippingIsNotEmpty;
|
||||
}
|
||||
}
|
||||
113
client/modules/crm/src/views/activities/list.js
Normal file
@@ -0,0 +1,113 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import ListRelatedView from 'views/list-related';
|
||||
|
||||
export default class ActivitiesListView extends ListRelatedView {
|
||||
|
||||
createButton = false
|
||||
unlinkDisabled = true
|
||||
filtersDisabled = true
|
||||
allResultDisabled = true;
|
||||
|
||||
setup() {
|
||||
this.rowActionsView = 'views/record/row-actions/default';
|
||||
|
||||
super.setup();
|
||||
|
||||
this.type = this.options.type;
|
||||
}
|
||||
|
||||
getHeader() {
|
||||
const name = this.model.get('name') || this.model.id;
|
||||
|
||||
const recordUrl = `#${this.scope}/view/${this.model.id}`;
|
||||
|
||||
const $name =
|
||||
$('<a>')
|
||||
.attr('href', recordUrl)
|
||||
.addClass('font-size-flexible title')
|
||||
.text(name)
|
||||
.css('user-select', 'none');
|
||||
|
||||
if (this.model.get('deleted')) {
|
||||
$name.css('text-decoration', 'line-through');
|
||||
}
|
||||
|
||||
const headerIconHtml = this.getHelper().getScopeColorIconHtml(this.foreignScope);
|
||||
const scopeLabel = this.getLanguage().translate(this.scope, 'scopeNamesPlural');
|
||||
|
||||
let $root = $('<span>').text(scopeLabel);
|
||||
|
||||
if (!this.rootLinkDisabled) {
|
||||
$root = $('<span>')
|
||||
.append(
|
||||
$('<a>')
|
||||
.attr('href', '#' + this.scope)
|
||||
.addClass('action')
|
||||
.attr('data-action', 'navigateToRoot')
|
||||
.text(scopeLabel)
|
||||
);
|
||||
}
|
||||
|
||||
$root.css('user-select', 'none');
|
||||
|
||||
if (headerIconHtml) {
|
||||
$root.prepend(headerIconHtml);
|
||||
}
|
||||
|
||||
const linkLabel = this.type === 'history' ? this.translate('History') : this.translate('Activities');
|
||||
|
||||
const $link = $('<span>').text(linkLabel);
|
||||
|
||||
$link
|
||||
.css('user-select', 'none');
|
||||
|
||||
const $target = $('<span>').text(this.translate(this.foreignScope, 'scopeNamesPlural'));
|
||||
|
||||
$target
|
||||
.css('user-select', 'none')
|
||||
.css('cursor', 'pointer')
|
||||
.attr('data-action', 'fullRefresh')
|
||||
.attr('title', this.translate('clickToRefresh', 'messages'))
|
||||
|
||||
return this.buildHeaderHtml([
|
||||
$root,
|
||||
$name,
|
||||
$link,
|
||||
$target,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
updatePageTitle() {
|
||||
this.setPageTitle(this.translate(this.foreignScope, 'scopeNamesPlural'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import MultiEnumFieldView from 'views/fields/multi-enum';
|
||||
|
||||
export default class extends MultiEnumFieldView {
|
||||
|
||||
setupOptions() {
|
||||
const entityType = this.model.get('name');
|
||||
|
||||
const options = this.getMetadata().get(['entityDefs', entityType, 'fields', 'status', 'options']) || [];
|
||||
|
||||
this.params.options = [...options];
|
||||
this.params.translation = `${entityType}.options.status`;
|
||||
}
|
||||
}
|
||||