Merge branch 'fix'

This commit is contained in:
Yuri Kuznetsov
2025-02-15 14:53:57 +02:00
9 changed files with 96 additions and 21 deletions
@@ -63,15 +63,12 @@ class RecordTree extends Record
return (object) $this->actionListTree($request->getRouteParams(), $request->getParsedBody(), $request);
}
$where = $request->getQueryParams()['where'] ?? null;
$selectParams = $this->fetchSearchParamsFromRequest($request);
$parentId = $request->getQueryParam('parentId');
$maxDepth = $request->getQueryParam('maxDepth');
$onlyNotEmpty = (bool) $request->getQueryParam('onlyNotEmpty');
if ($where !== null && !is_array($where)) {
throw new BadRequest();
}
if ($maxDepth !== null) {
$maxDepth = (int) $maxDepth;
}
@@ -79,7 +76,7 @@ class RecordTree extends Record
$collection = $this->getRecordTreeService()->getTree(
$parentId,
[
'where' => $where,
'where' => $selectParams->getWhere(),
'onlyNotEmpty' => $onlyNotEmpty,
],
$maxDepth
+7 -3
View File
@@ -64,7 +64,7 @@ class RecordTree extends Record
protected $categoryField = null;
/**
* @param array<string, mixed> $params
* @param array{where?: ?WhereItem, onlyNotEmpty?: bool} $params
* @return ?Collection<Entity>
* @throws Forbidden
* @throws BadRequest
@@ -84,7 +84,7 @@ class RecordTree extends Record
}
/**
* @param array<string, mixed> $params
* @param array{where?: ?WhereItem, onlyNotEmpty?: bool} $params
* @return ?Collection<Entity>
* @throws BadRequest
* @throws Forbidden
@@ -104,7 +104,11 @@ class RecordTree extends Record
return null;
}
$searchParams = SearchParams::fromRaw($params);
$searchParams = SearchParams::create();
if (isset($params['where'])) {
$searchParams = $searchParams->withWhere($params['where']);
}
$selectBuilder = $this->selectBuilderFactory
->create()
@@ -453,7 +453,7 @@ class CalendarView extends View {
start + this.rangeSeparator + end :
start;
} else {
title = moment(view.currentStart).format(format);
title = this.dateToMoment(view.currentStart).format(format);
}
if (this.options.userId && this.options.userName) {
+5 -6
View File
@@ -1,16 +1,15 @@
<div class="row">
<div class="{{#if hasSide}}col-md-10 col-sm-10 col-xs-12{{else}}col-md-12{{/if}}">
<div class="formula-edit-container">
<div>
<div id="{{containerId}}">{{value}}</div>
</div>
{{#if hasSide}}
<div class="col-md-2 col-sm-2 col-xs-12">
<div>
<div class="button-container">
<div class="btn-group pull-right">
{{#if hasCheckSyntax}}
<button
type="button"
class="btn btn-default btn-sm btn-icon"
class="btn btn-text btn-sm btn-icon"
data-action="checkSyntax"
title="{{translate 'Check Syntax' scope='Formula'}}"
><span class="far fa-circle"></span></button>
@@ -18,7 +17,7 @@
{{#if hasInsert}}
<button
type="button"
class="btn btn-default btn-sm dropdown-toggle btn-icon"
class="btn btn-text btn-sm dropdown-toggle btn-icon"
data-toggle="dropdown"
><span class="fas fa-plus"></span></button>
<ul class="dropdown-menu pull-right">
+17 -1
View File
@@ -58,6 +58,8 @@ class SelectRelatedHelper {
* primaryFilterName?: string,
* boolFilterList?: string[]|string,
* viewKey?: string,
* hasCreate?: boolean,
* onCreate?: function(): void,
* }} options
*/
process(model, link, options = {}) {
@@ -159,10 +161,14 @@ class SelectRelatedHelper {
const orderBy = filters.orderBy || panelDefs.selectOrderBy;
const orderDirection = filters.orderBy ? filters.order : panelDefs.selectOrderDirection;
const createButton = options.hasCreate === true && options.onCreate !== undefined;
/** @type {import('views/modals/select-records').default} */
let modalView;
this.view.createView('dialogSelectRelated', viewName, {
scope: scope,
multiple: true,
triggerCreateEvent: true,
filters: advanced,
massRelateEnabled: massRelateEnabled,
primaryFilterName: primaryFilterName,
@@ -171,7 +177,17 @@ class SelectRelatedHelper {
layoutName: panelDefs.selectLayout,
orderBy: orderBy,
orderDirection: orderDirection,
createButton: createButton,
onCreate: () => {
modalView.close();
if (options.onCreate) {
options.onCreate();
}
},
}, view => {
modalView = view;
view.render();
Espo.Ui.notify(false);
@@ -171,6 +171,23 @@ class GlobalSearchView extends SiteNavbarItemView {
return false;
})
.sort((a, b) => {
if (
a.lowerLabel.startsWith(lower) &&
!b.lowerLabel.startsWith(lower)
) {
return -1;
}
if (
!a.lowerLabel.startsWith(lower) &&
b.lowerLabel.startsWith(lower)
) {
return 1;
}
return a.lowerLabel.localeCompare(b.lowerLabel);
})
.map(it => ({
value: it.label,
url: it.url,
@@ -331,10 +348,9 @@ class GlobalSearchView extends SiteNavbarItemView {
*/
getTabDataList() {
/** @type {module:views/global-search/global-search~tabData[]}*/
const list = [];
let list = [];
/**
*
* @param {string|TabsHelper~item} item
* @return {module:views/global-search/global-search~tabData}
*/
@@ -351,9 +367,13 @@ class GlobalSearchView extends SiteNavbarItemView {
};
};
/**
* @param {string|TabsHelper~item} item
* @return {boolean}
*/
const checkTab = (item) => {
return (this.tabsHelper.isTabScope(item) || this.tabsHelper.isTabUrl(item)) &&
this.tabsHelper.checkTabAccess(item)
this.tabsHelper.checkTabAccess(item);
}
for (const item of this.tabsHelper.getTabList()) {
@@ -392,6 +412,7 @@ class GlobalSearchView extends SiteNavbarItemView {
.forEach(it => {
it.itemList
.filter(it => it.tabQuickSearch && it.label)
.filter(it => !list.find(subIt => subIt.url === it.url))
.forEach(it => {
const label = this.translate(it.label, 'labels', 'Admin');
@@ -405,6 +426,12 @@ class GlobalSearchView extends SiteNavbarItemView {
});
}
list = list
.filter((it, i) => {
return list.findIndex(subIt => subIt.url === it.url) === i &&
list.findIndex(subIt => subIt.lowerLabel === it.lowerLabel) === i
});
/** @type {Record<string, {tab: boolean}>} */
const scopes = this.getMetadata().get('scopes') || {};
+13
View File
@@ -100,6 +100,7 @@ class SelectRecordsModalView extends ModalView {
* @property {function(): Promise<Record>} [createAttributesProvider] Create-attributes provider.
* @property {Record} [createAttributes] Create-attributes.
* @property {function(import('model').default[])} [onSelect] On record select. As of 9.0.0.
* @property {function()} [onCreate] On create click. As of 9.0.5.
*/
/**
@@ -113,6 +114,11 @@ class SelectRecordsModalView extends ModalView {
/** @private */
this.onSelect = options.onSelect;
}
if (options.onCreate) {
/** @private */
this.onCreate = options.onCreate;
}
}
data() {
@@ -388,6 +394,13 @@ class SelectRecordsModalView extends ModalView {
}
create() {
if (this.onCreate) {
this.onCreate();
return;
}
// @todo Remove in v9.1.0. Kept bc.
if (this.options.triggerCreateEvent) {
this.trigger('create');
@@ -885,7 +885,10 @@ class RelationshipPanelView extends BottomPanelView {
actionSelectRelated() {
const helper = new SelectRelatedHelper(this);
helper.process(this.model, this.link);
helper.process(this.model, this.link, {
hasCreate: this.defs.create,
onCreate: () => this.actionCreateRelated(),
});
}
/**
+16
View File
@@ -4218,6 +4218,22 @@ body > .autocomplete-suggestions.text-search-suggestions {
}
}
.formula-edit-container {
&:has(> :last-child:nth-child(2)) {
clear: both;
> div:first-child {
float: left;
width: calc(100% - var(--70px));
}
> div:last-child {
float: right;
width: var(--70px);
}
}
}
@import "misc/kanban.less";
@import "misc/wysiwyg.less";