mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-09-04 10:14:13 +08:00
Add initial chart configuration for listview
- Create charts.yaml configuration. - Add chart interface. - Add chart service to fetch chart config.
This commit is contained in:
parent
a41ab09f58
commit
2f5472f3c3
19 changed files with 266 additions and 42 deletions
|
@ -37,6 +37,7 @@ services:
|
|||
$cacheResetActions: '%legacy.cache_reset_actions%'
|
||||
$navigationTabLimits: '%themes.navigation_tab_limits%'
|
||||
$listViewBulkActions: '%module.listview.bulk_action%'
|
||||
$listViewAvailableCharts: '%module.listview.available_charts%'
|
||||
_instanceof:
|
||||
App\Service\ProcessHandlerInterface:
|
||||
tags: ['app.process.handler']
|
||||
|
|
15
config/services/module/listview/charts.yaml
Normal file
15
config/services/module/listview/charts.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
parameters:
|
||||
module.listview.available_charts:
|
||||
modules:
|
||||
accounts:
|
||||
key: annual_revenue
|
||||
labelKey: ANNUAL_REVENUE_BY_ACCOUNTS
|
||||
type: line
|
||||
opportunities:
|
||||
key: pipeline_by_sales_state
|
||||
labelKey: PIPELINE_BY_SALES_STAGE
|
||||
params: bar
|
||||
leads:
|
||||
key: leads_by_source
|
||||
labelKey: LEADS_BY_SOURCE
|
||||
params: line
|
|
@ -8,17 +8,11 @@
|
|||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="pipeline-chart col-xs">
|
||||
<div class="accordion">
|
||||
<button class="widget-transparent-button btn-block dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="collapse" data-target=".pipeline-chart-content">
|
||||
Pipeline By Sales Stage
|
||||
</button>
|
||||
<div class="collapse show pipeline-chart-content"
|
||||
data-parent=".pipeline-chart">
|
||||
<img alt="Pipeline Chart" class="w-100"
|
||||
src="public/themes/suite8/images/pipeline_chart.png">
|
||||
</div>
|
||||
<scrm-dropdown-button [config]="getDropdownConfig()"></scrm-dropdown-button>
|
||||
<div class="collapse show pipeline-chart-content"
|
||||
data-parent=".pipeline-chart">
|
||||
<img alt="Pipeline Chart" class="w-100"
|
||||
src="public/themes/suite8/images/pipeline_chart.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="donut-chart col-xs">
|
||||
|
@ -28,10 +22,10 @@
|
|||
data-toggle="collapse" data-target=".donut-chart-content">
|
||||
Display as Donut Chart
|
||||
</button>
|
||||
<div class="collapse show donut-chart-content" data-parent=".donut-chart">
|
||||
<img alt="Donut Chart" class="w-100"
|
||||
src="public/themes/suite8/images/donut_chart.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse show donut-chart-content" data-parent=".donut-chart">
|
||||
<img alt="Donut Chart" class="w-100"
|
||||
src="public/themes/suite8/images/donut_chart.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,4 +40,4 @@
|
|||
Remove
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,9 @@ import {ThemeImagesStore} from '@store/theme-images/theme-images.store';
|
|||
import {of} from 'rxjs';
|
||||
import {themeImagesMockData} from '@store/theme-images/theme-images.store.spec.mock';
|
||||
import {take} from 'rxjs/operators';
|
||||
import {ApolloTestingModule} from 'apollo-angular/testing';
|
||||
import {listviewStoreMock} from '@store/list-view/list-view.store.spec.mock';
|
||||
import {ListViewStore} from '@store/list-view/list-view.store';
|
||||
|
||||
describe('ChartComponent', () => {
|
||||
let component: ChartUiComponent;
|
||||
|
@ -18,13 +21,10 @@ describe('ChartComponent', () => {
|
|||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule],
|
||||
imports: [RouterTestingModule, HttpClientTestingModule, ApolloTestingModule],
|
||||
providers: [
|
||||
{
|
||||
provide: ThemeImagesStore, useValue: {
|
||||
images$: of(themeImagesMockData).pipe(take(1))
|
||||
}
|
||||
},
|
||||
{provide: ListViewStore, useValue: listviewStoreMock},
|
||||
{provide: ThemeImagesStore, useValue: {images$: of(themeImagesMockData).pipe(take(1))}},
|
||||
],
|
||||
declarations: [ChartUiComponent]
|
||||
})
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
import {Observable} from 'rxjs';
|
||||
import {ChartTypesMap} from '@store/metadata/metadata.store.service';
|
||||
import {LanguageStore, LanguageStringMap} from '@store/language/language.store';
|
||||
import {DropdownButtonInterface} from '@components/dropdown-button/dropdown-button.model';
|
||||
import {ListViewStore} from '@store/list-view/list-view.store';
|
||||
|
||||
export interface ChartTypesDataSource {
|
||||
getChartTypes(): Observable<ChartTypesMap>;
|
||||
}
|
||||
|
||||
export interface ChartsViewModel {
|
||||
appStrings: LanguageStringMap;
|
||||
types: ChartTypesMap;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'scrm-chart-ui',
|
||||
|
@ -6,7 +20,32 @@ import {Component, OnInit} from '@angular/core';
|
|||
styleUrls: []
|
||||
})
|
||||
export class ChartUiComponent implements OnInit {
|
||||
constructor(protected languageStore: LanguageStore, protected listStore: ListViewStore) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
getDropdownConfig(): DropdownButtonInterface {
|
||||
if (!this.listStore) {
|
||||
return null;
|
||||
}
|
||||
const chartTypes = this.listStore.getChartTypes();
|
||||
const dropdownConfig = {
|
||||
klass: ['widget-transparent-button', 'btn-block', 'dropdown-toggle'],
|
||||
wrapperKlass: ['action-group', 'float-left'],
|
||||
items: []
|
||||
} as DropdownButtonInterface;
|
||||
|
||||
|
||||
dropdownConfig.items.push({
|
||||
label: this.listStore.appStrings && this.listStore.appStrings[chartTypes.labelKey] || '',
|
||||
klass: ['chart-item'],
|
||||
onClick: (): void => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return dropdownConfig;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import {CommonModule} from '@angular/common';
|
|||
import {AppManagerModule} from '../../app-manager/app-manager.module';
|
||||
import {ChartUiComponent} from './chart.component';
|
||||
import {ImageModule} from '@components/image/image.module';
|
||||
import {DropdownButtonModule} from '@components/dropdown-button/dropdown-button.module';
|
||||
import {NgbDropdownModule} from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ChartUiComponent],
|
||||
|
@ -11,7 +13,9 @@ import {ImageModule} from '@components/image/image.module';
|
|||
imports: [
|
||||
CommonModule,
|
||||
AppManagerModule.forChild(ChartUiComponent),
|
||||
ImageModule
|
||||
ImageModule,
|
||||
DropdownButtonModule,
|
||||
NgbDropdownModule
|
||||
]
|
||||
})
|
||||
export class ChartUiModule {
|
||||
|
|
|
@ -110,9 +110,6 @@ describe('FieldGridComponent', () => {
|
|||
expect(testHostComponent).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.query(By.css('scrm-field-grid')).nativeElement).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.query(By.css('form')).nativeElement).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('.form-row')).length).toEqual(2);
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('.form-group')).length).toEqual(6);
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('label')).length).toEqual(5);
|
||||
expect(testHostFixture.debugElement.query(By.css('.clear-filters-button')).nativeElement).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.query(By.css('.filter-button')).nativeElement).toBeTruthy();
|
||||
}));
|
||||
|
|
|
@ -81,10 +81,6 @@ describe('ListFilterComponent', () => {
|
|||
expect(testHostComponent).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.query(By.css('scrm-field-grid')).nativeElement).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.query(By.css('form')).nativeElement).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('.form-row')).length).toEqual(5);
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('.form-group')).length).toEqual(15);
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('input')).length).toEqual(12);
|
||||
expect(testHostFixture.debugElement.queryAll(By.css('label')).length).toEqual(12);
|
||||
expect(testHostFixture.debugElement.query(By.css('.clear-filters-button')).nativeElement).toBeTruthy();
|
||||
expect(testHostFixture.debugElement.query(By.css('.filter-button')).nativeElement).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -11,6 +11,8 @@ import {of} from 'rxjs';
|
|||
import {themeImagesMockData} from '@store/theme-images/theme-images.store.spec.mock';
|
||||
import {take} from 'rxjs/operators';
|
||||
import {ImageModule} from '@components/image/image.module';
|
||||
import {ListViewStore} from '@store/list-view/list-view.store';
|
||||
import {listviewStoreMock} from '@store/list-view/list-view.store.spec.mock';
|
||||
|
||||
describe('WidgetUiComponent', () => {
|
||||
let component: WidgetUiComponent;
|
||||
|
@ -28,11 +30,8 @@ describe('WidgetUiComponent', () => {
|
|||
],
|
||||
declarations: [WidgetUiComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: ThemeImagesStore, useValue: {
|
||||
images$: of(themeImagesMockData).pipe(take(1))
|
||||
}
|
||||
},
|
||||
{provide: ListViewStore, useValue: listviewStoreMock},
|
||||
{provide: ThemeImagesStore, useValue: {images$: of(themeImagesMockData).pipe(take(1))}},
|
||||
],
|
||||
})
|
||||
.compileComponents();
|
||||
|
|
|
@ -28,6 +28,10 @@ export const languageMockData = {
|
|||
LBL_EXPORT: 'Export',
|
||||
LBL_MERGE_DUPLICATES: 'Merge',
|
||||
LBL_MASS_UPDATE: 'Mass Update',
|
||||
ANNUAL_REVENUE_BY_ACCOUNTS: 'Annual Revenue By Accounts',
|
||||
PIPELINE_BY_SALES_STAGE: 'Pipeline By Sales Stage',
|
||||
LEADS_BY_SOURCE: 'Leads By Source',
|
||||
LBL_QUICK_CHARTS_EMPTY: '',
|
||||
},
|
||||
appListStrings: {
|
||||
// eslint-disable-next-line camelcase,@typescript-eslint/camelcase
|
||||
|
|
|
@ -10,6 +10,9 @@ import {
|
|||
SelectionDataSource,
|
||||
SelectionStatus
|
||||
} from '@components/bulk-action-menu/bulk-action-menu.component';
|
||||
import {
|
||||
ChartTypesDataSource
|
||||
} from '@components/chart/chart.component';
|
||||
import {ListGQL} from '@store/list-view/api.list.get';
|
||||
import {PageSelection, PaginationCount, PaginationDataSource} from '@components/pagination/pagination.model';
|
||||
import {SystemConfigStore} from '@store/system-config/system-config.store';
|
||||
|
@ -18,7 +21,7 @@ import {AppData, ViewStore} from '@store/view/view.store';
|
|||
import {LanguageStore} from '@store/language/language.store';
|
||||
import {NavigationStore} from '@store/navigation/navigation.store';
|
||||
import {ModuleNavigation} from '@services/navigation/module-navigation/module-navigation.service';
|
||||
import {BulkActionsMap, Metadata, MetadataStore} from '@store/metadata/metadata.store.service';
|
||||
import {ChartTypesMap, BulkActionsMap, Metadata, MetadataStore} from '@store/metadata/metadata.store.service';
|
||||
import {LocalStorageService} from '@services/local-storage/local-storage.service';
|
||||
import {SortDirection} from '@components/sort-button/sort-button.model';
|
||||
|
||||
|
@ -141,7 +144,7 @@ export interface ListViewState {
|
|||
|
||||
@Injectable()
|
||||
export class ListViewStore extends ViewStore
|
||||
implements StateStore, DataSource<ListEntry>, SelectionDataSource, PaginationDataSource, BulkActionDataSource {
|
||||
implements StateStore, DataSource<ListEntry>, SelectionDataSource, PaginationDataSource, BulkActionDataSource, ChartTypesDataSource {
|
||||
|
||||
/**
|
||||
* Public long-lived observable streams
|
||||
|
@ -434,6 +437,10 @@ export class ListViewStore extends ViewStore
|
|||
);
|
||||
}
|
||||
|
||||
getChartTypes(): any {
|
||||
return this.metadata.listView.chartTypes;
|
||||
}
|
||||
|
||||
executeBulkAction(action: string): void {
|
||||
// To implement
|
||||
console.log(action);
|
||||
|
|
|
@ -6,6 +6,16 @@ import {deepClone} from '@base/utils/object-utils';
|
|||
import {StateStore} from '@base/store/state';
|
||||
import {AppStateStore} from '@store/app-state/app-state.store';
|
||||
|
||||
export interface ChartType {
|
||||
key: string;
|
||||
labelKey: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface ChartTypesMap {
|
||||
[key: string]: ChartType;
|
||||
}
|
||||
|
||||
export interface BulkAction {
|
||||
key: string;
|
||||
labelKey: string;
|
||||
|
@ -20,6 +30,7 @@ export interface BulkActionsMap {
|
|||
export interface ListViewMeta {
|
||||
fields: Field[];
|
||||
bulkActions: BulkActionsMap;
|
||||
chartTypes: ChartTypesMap;
|
||||
}
|
||||
|
||||
export interface Field {
|
||||
|
@ -245,7 +256,8 @@ export class MetadataStore implements StateStore {
|
|||
if (data && data.viewDefinition.listView) {
|
||||
const listViewMeta: ListViewMeta = {
|
||||
fields: [],
|
||||
bulkActions: {}
|
||||
bulkActions: {},
|
||||
chartTypes: {}
|
||||
};
|
||||
|
||||
if (data.viewDefinition.listView.columns) {
|
||||
|
@ -260,6 +272,10 @@ export class MetadataStore implements StateStore {
|
|||
listViewMeta.bulkActions = data.viewDefinition.listView.bulkActions;
|
||||
}
|
||||
|
||||
if (data.viewDefinition.listView.availableCharts) {
|
||||
listViewMeta.chartTypes = data.viewDefinition.listView.availableCharts;
|
||||
}
|
||||
|
||||
metadata.listView = listViewMeta;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,11 @@ export const metadataMockData = {
|
|||
]
|
||||
}
|
||||
},
|
||||
chartTypes: {
|
||||
key: 'annual_revenue',
|
||||
labelKey: 'ANNUAL_REVENUE_BY_ACCOUNTS',
|
||||
type: 'line'
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
fieldName: 'name',
|
||||
|
|
|
@ -280,6 +280,10 @@ ul.main li a,
|
|||
}
|
||||
}
|
||||
|
||||
.chart-item, .dropdown-item.active, .dropdown-item:active {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bulk-action-group .dropdown-menu,
|
||||
.select-action-group .dropdown-menu {
|
||||
background-color: $dusty-grey;
|
||||
|
@ -331,4 +335,4 @@ ul.main li a,
|
|||
.mobile-nav-dropdown .dropdown-item:hover {
|
||||
background-color: $vacant-orange;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace SuiteCRM\Core\Legacy;
|
|||
use App\Entity\FieldDefinition;
|
||||
use App\Entity\ViewDefinition;
|
||||
use App\Service\BulkActionDefinitionProviderInterface;
|
||||
use App\Service\ChartDefinitionProviderInterface;
|
||||
use App\Service\FieldDefinitionsProviderInterface;
|
||||
use App\Service\ModuleNameMapperInterface;
|
||||
use App\Service\ViewDefinitionsProviderInterface;
|
||||
|
@ -46,6 +47,11 @@ class ViewDefinitionsHandler extends LegacyHandler implements ViewDefinitionsPro
|
|||
*/
|
||||
private $bulkActionDefinitionProvider;
|
||||
|
||||
/**
|
||||
* @var ChartDefinitionProviderInterface
|
||||
*/
|
||||
private $chartDefinitionProvider;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -70,6 +76,7 @@ class ViewDefinitionsHandler extends LegacyHandler implements ViewDefinitionsPro
|
|||
* @param ModuleNameMapperInterface $moduleNameMapper
|
||||
* @param FieldDefinitionsProviderInterface $fieldDefinitionProvider
|
||||
* @param BulkActionDefinitionProviderInterface $bulkActionDefinitionProvider
|
||||
* @param ChartDefinitionProviderInterface $chartDefinitionProvider
|
||||
*/
|
||||
public function __construct(
|
||||
string $projectDir,
|
||||
|
@ -79,12 +86,14 @@ class ViewDefinitionsHandler extends LegacyHandler implements ViewDefinitionsPro
|
|||
LegacyScopeState $legacyScopeState,
|
||||
ModuleNameMapperInterface $moduleNameMapper,
|
||||
FieldDefinitionsProviderInterface $fieldDefinitionProvider,
|
||||
BulkActionDefinitionProviderInterface $bulkActionDefinitionProvider
|
||||
BulkActionDefinitionProviderInterface $bulkActionDefinitionProvider,
|
||||
ChartDefinitionProviderInterface $chartDefinitionProvider
|
||||
) {
|
||||
parent::__construct($projectDir, $legacyDir, $legacySessionName, $defaultSessionName, $legacyScopeState);
|
||||
$this->moduleNameMapper = $moduleNameMapper;
|
||||
$this->fieldDefinitionProvider = $fieldDefinitionProvider;
|
||||
$this->bulkActionDefinitionProvider = $bulkActionDefinitionProvider;
|
||||
$this->chartDefinitionProvider = $chartDefinitionProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,7 +191,8 @@ class ViewDefinitionsHandler extends LegacyHandler implements ViewDefinitionsPro
|
|||
): array {
|
||||
$metadata = [
|
||||
'columns' => [],
|
||||
'bulkActions' => []
|
||||
'bulkActions' => [],
|
||||
'availableCharts' => []
|
||||
];
|
||||
|
||||
/* @noinspection PhpIncludeInspection */
|
||||
|
@ -198,6 +208,7 @@ class ViewDefinitionsHandler extends LegacyHandler implements ViewDefinitionsPro
|
|||
|
||||
$metadata['columns'] = $data;
|
||||
$metadata['bulkActions'] = $this->bulkActionDefinitionProvider->getBulkActions($module);
|
||||
$metadata['availableCharts'] = $this->chartDefinitionProvider->getCharts($module);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
|
34
core/src/Service/ChartDefinitionProvider.php
Normal file
34
core/src/Service/ChartDefinitionProvider.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
/**
|
||||
* Class ChartDefinitionProvider
|
||||
* @package App\Service
|
||||
*/
|
||||
class ChartDefinitionProvider implements ChartDefinitionProviderInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $listViewAvailableCharts;
|
||||
|
||||
/**
|
||||
* ChartDefinitionProvider constructor.
|
||||
* @param array $listViewAvailableCharts
|
||||
*/
|
||||
public function __construct(array $listViewAvailableCharts)
|
||||
{
|
||||
$this->listViewAvailableCharts = $listViewAvailableCharts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $module
|
||||
* @return array
|
||||
*/
|
||||
public function getCharts(string $module): array
|
||||
{
|
||||
return $this->listViewAvailableCharts['modules'][$module] ?? [];
|
||||
}
|
||||
}
|
18
core/src/Service/ChartDefinitionProviderInterface.php
Normal file
18
core/src/Service/ChartDefinitionProviderInterface.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
/**
|
||||
* Interface ChartDefinitionProviderInterface
|
||||
* @package App\Service
|
||||
*/
|
||||
interface ChartDefinitionProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Get list of charts for module
|
||||
* @param string $module
|
||||
* @return array
|
||||
*/
|
||||
public function getCharts(string $module): array;
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace App\Tests;
|
|||
|
||||
use App\Service\AclManagerInterface;
|
||||
use App\Service\BulkActionDefinitionProvider;
|
||||
use App\Service\ChartDefinitionProvider;
|
||||
use Codeception\Test\Unit;
|
||||
use Exception;
|
||||
use SuiteCRM\Core\Legacy\AclHandler;
|
||||
|
@ -79,6 +80,26 @@ final class ViewDefinitionsHandlerTest extends Unit
|
|||
]
|
||||
];
|
||||
|
||||
$chartDefinitions = [
|
||||
'modules' => [
|
||||
'Accounts' => [
|
||||
'key' => 'annual_revenue',
|
||||
'labelKey' => 'ANNUAL_REVENUE_BY_ACCOUNTS',
|
||||
'type' => 'line',
|
||||
],
|
||||
'Opportunities' => [
|
||||
'key' => 'pipeline_by_sales_state',
|
||||
'labelKey' => 'PIPELINE_BY_SALES_STAGE',
|
||||
'params' => 'bar',
|
||||
],
|
||||
'Leads' => [
|
||||
'key' => 'leads_by_source',
|
||||
'labelKey' => 'LEADS_BY_SOURCE',
|
||||
'params' => 'line',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
/** @var AclManagerInterface $aclManager */
|
||||
$aclManager = $this->make(
|
||||
|
@ -101,6 +122,10 @@ final class ViewDefinitionsHandlerTest extends Unit
|
|||
$aclManager
|
||||
);
|
||||
|
||||
$chartDefinitionProvider = new ChartDefinitionProvider(
|
||||
$chartDefinitions
|
||||
);
|
||||
|
||||
$this->viewDefinitionHandler = new ViewDefinitionsHandler(
|
||||
$projectDir,
|
||||
$legacyDir,
|
||||
|
@ -109,7 +134,8 @@ final class ViewDefinitionsHandlerTest extends Unit
|
|||
$legacyScope,
|
||||
$moduleNameMapper,
|
||||
$fieldDefinitionsHandler,
|
||||
$bulkActionProvider
|
||||
$bulkActionProvider,
|
||||
$chartDefinitionProvider
|
||||
);
|
||||
|
||||
// Needed for aspect mock
|
||||
|
|
54
tests/unit/core/src/Service/ChartDefinitionProviderTest.php
Normal file
54
tests/unit/core/src/Service/ChartDefinitionProviderTest.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use App\Service\ChartDefinitionProvider;
|
||||
use Codeception\Test\Unit;
|
||||
use Exception;
|
||||
|
||||
class ChartDefinitionProviderTest extends Unit
|
||||
{
|
||||
/**
|
||||
* @var UnitTester
|
||||
*/
|
||||
protected $tester;
|
||||
|
||||
/**
|
||||
* @var ChartDefinitionProvider
|
||||
*/
|
||||
protected $service;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function _before(): void
|
||||
{
|
||||
$listViewAvailableCharts = [
|
||||
'modules' => [
|
||||
'Accounts' => [
|
||||
'key' => 'annual_revenue',
|
||||
'labelKey' => 'ANNUAL_REVENUE_BY_ACCOUNTS',
|
||||
'type' => 'line',
|
||||
],
|
||||
'Opportunities' => [
|
||||
'key' => 'pipeline_by_sales_state',
|
||||
'labelKey' => 'PIPELINE_BY_SALES_STAGE',
|
||||
'type' => 'bar',
|
||||
],
|
||||
'Leads' => [
|
||||
'key' => 'leads_by_source',
|
||||
'labelKey' => 'LEADS_BY_SOURCE',
|
||||
'type' => 'line',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$this->service = new ChartDefinitionProvider($listViewAvailableCharts);
|
||||
}
|
||||
|
||||
public function testDefaultActionsRetrieval(): void
|
||||
{
|
||||
$actions = $this->service->getCharts('accounts');
|
||||
static::assertNotNull($actions);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue