mirror of
https://github.com/fleetbase/fleetbase.git
synced 2026-01-08 07:16:49 +00:00
fixed gridstack
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
<div class="fleetbase-dashboard-grid">
|
||||
<div class="grid grid-cols-1 md:grid-cols-12 gap-4">
|
||||
<Button @type="default" @icon="add" @helpText={{"Add new widgets to Dashbord"}} @onClick={{this.openWidget}} />
|
||||
{{#each this.dashboards as |dashboard index|}}
|
||||
<Dashboard::Create @index={{index}} @dashboard={{dashboard}} />
|
||||
{{/each}}
|
||||
<Dashboard::WidgetPanel @isOpen={{this.isOpenWidget}} />
|
||||
|
||||
<div class="flex flex-row">
|
||||
<Button @type="default" @icon="add" @helpText={{"Add new widgets to Dashbord"}} @onClick={{this.openWidgetSelector}} />
|
||||
</div>
|
||||
</div>
|
||||
<Dashboard::Create @dashboard={{this.currentDashboard}} />
|
||||
</div>
|
||||
|
||||
<Dashboard::WidgetPanel @isOpen={{this.isSelectingWidgets}} @onLoad={{this.setWidgetSelectorPanelContext}} @dashboard={{this.currentDashboard}} />
|
||||
@@ -2,55 +2,35 @@ import Component from '@glimmer/component';
|
||||
import loadExtensions from '@fleetbase/ember-core/utils/load-extensions';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { isArray } from '@ember/array';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { task } from 'ember-concurrency-decorators';
|
||||
|
||||
export default class DashboardComponent extends Component {
|
||||
@service fetch;
|
||||
@tracked extensions;
|
||||
@service store;
|
||||
@tracked dashboards = [];
|
||||
@tracked isLoading;
|
||||
@tracked isOpenWidget = false;
|
||||
@tracked currentDashboard;
|
||||
@tracked isSelectingWidgets = false;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.loadExtensions();
|
||||
this.loadDashboards.perform();
|
||||
}
|
||||
|
||||
@action async loadExtensions() {
|
||||
this.extensions = await loadExtensions();
|
||||
console.log('Extensions:', this.extensions);
|
||||
this.loadDashboardBuilds.perform();
|
||||
@task *loadDashboards() {
|
||||
this.dashboards = yield this.store.findAll('dashboard');
|
||||
this.currentDashboard = this.dashboards[0];
|
||||
}
|
||||
|
||||
@task *loadDashboard(extension) {
|
||||
this.isLoading = extension.extension;
|
||||
let dashboardBuild;
|
||||
|
||||
try {
|
||||
dashboardBuild = yield this.fetch.get(extension.fleetbase.dashboard, {}, { namespace: '' });
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isArray(dashboardBuild)) {
|
||||
this.dashboards = [...this.dashboards, ...dashboardBuild.map((build) => ({ ...build, extension }))];
|
||||
}
|
||||
@action selectDashboard(dashboard) {
|
||||
this.currentDashboard = dashboard;
|
||||
}
|
||||
|
||||
@task({ enqueue: true, maxConcurrency: 1 }) *loadDashboardBuilds() {
|
||||
const extensionsWithDashboards = this.extensions.filter((extension) => typeof extension.fleetbase?.dashboard === 'string');
|
||||
console.log('Extensions with Dashboards:', extensionsWithDashboards);
|
||||
|
||||
for (let i = 0; i < extensionsWithDashboards.length; i++) {
|
||||
const extension = extensionsWithDashboards[i];
|
||||
yield this.loadDashboard.perform(extension);
|
||||
}
|
||||
@action setWidgetSelectorPanelContext(widgetSelectorContext) {
|
||||
this.widgetSelectorContext = widgetSelectorContext;
|
||||
console.log('widgetSelectorContext', widgetSelectorContext);
|
||||
}
|
||||
|
||||
@action openWidget() {
|
||||
this.isOpenWidget = !this.isOpenWidget;
|
||||
console.log(this.isOpenWidget);
|
||||
@action openWidgetSelector() {
|
||||
this.isSelectingWidgets = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,13 @@
|
||||
<div class="col-span-{{or @dashboard.size 12}}">
|
||||
<div class="dashboard-title flex flex-col lg:flex-row lg:items-center">
|
||||
<div class="flex flex-row items-center mb-2 lg:mb-0">
|
||||
{{#if this.isLoading}}
|
||||
<Spinner class="mr-2i" />
|
||||
{{/if}}
|
||||
<h2 class="text-sm font-bold dark:text-gray-100 text-black">{{@dashboard.title}}</h2>
|
||||
</div>
|
||||
<div>
|
||||
<Dashboard::QueryParams @params={{@dashboard.queryParams}} @onChange={{this.onQueryParamsChanged}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 lg:grid-cols-12 gap-4">
|
||||
{{#each this.dashboard.widgets as |widget|}}
|
||||
{{component (concat "dashboard/" widget.component) options=widget.options}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<GridStack>
|
||||
<GridStackItem @options={{hash x=0 y=0 w=6 h=2}}>
|
||||
Widget #1
|
||||
</GridStackItem>
|
||||
</GridStack>
|
||||
|
||||
<GridStack @options={{hash animate=true column=12 maxRow=10}}>
|
||||
<div class="fleetbase-dashboard-grid" ...attributes>
|
||||
<GridStack
|
||||
@options={{hash float=true animate=true acceptWidgets=true}}
|
||||
@onChange={{this.onChangeGrid}}
|
||||
@dragInOptions={{hash selector="test" options=(hash appendTo="body" helper="clone")}}
|
||||
>
|
||||
{{#each this.dashboard.widgets as |widget index|}}
|
||||
<GridStackItem @options={{hash w=3 h=3 autoPosition=true}} class="min-w-16">
|
||||
{{component (concat "dashboard/" widget.component) options=widget.options}}
|
||||
<GridStackItem @options={{widget.gridOptions}}>
|
||||
{{component widget.component options=widget.options}}
|
||||
</GridStackItem>
|
||||
{{/each}}
|
||||
</GridStack>
|
||||
|
||||
<WidgetGridStack::WidgetGridStack @options={{hash float=false animate=false}} class="w-full grid gap-4 grid-cols-3 grid-rows-3">
|
||||
{{#each this.dashboard.widgets as |widget index|}}
|
||||
<WidgetGridStack::WidgetGridStackItem @options={{hash w=2 h=2}}>
|
||||
{{component (concat "dashboard/" widget.component) options=widget.options}}
|
||||
</WidgetGridStack::WidgetGridStackItem>
|
||||
{{/each}}
|
||||
</WidgetGridStack::WidgetGridStack>
|
||||
|
||||
</div>
|
||||
@@ -2,40 +2,111 @@ import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { isArray } from '@ember/array';
|
||||
import { isArray, A } from '@ember/array';
|
||||
import { task } from 'ember-concurrency-decorators';
|
||||
import FleetbaseBlogComponent from '../fleetbase-blog';
|
||||
import GithubCardComponent from '../github-card';
|
||||
import DashboardCountComponent from './count';
|
||||
|
||||
export default class DashboardCreateComponent extends Component {
|
||||
@service fetch;
|
||||
@tracked isLoading = false;
|
||||
@tracked dashboard;
|
||||
|
||||
constructor() {
|
||||
constructor(owner, { dashboard }) {
|
||||
super(...arguments);
|
||||
this.dashboard = this.args.dashboard;
|
||||
|
||||
this.dashboard = {
|
||||
title: 'Fleetops stats',
|
||||
widgets: [
|
||||
{
|
||||
name: 'Blog',
|
||||
component: FleetbaseBlogComponent,
|
||||
gridOptions: { w: 8, h: 3, minW: 2 },
|
||||
options: {},
|
||||
},
|
||||
{
|
||||
name: 'Github',
|
||||
component: GithubCardComponent,
|
||||
gridOptions: { w: 4, h: 3, minW: 2 },
|
||||
options: {},
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2, minW: 2 },
|
||||
options: {
|
||||
format: 'money',
|
||||
value: '150',
|
||||
currency: '$',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2, minW: 2 },
|
||||
options: {
|
||||
format: 'money',
|
||||
value: '150',
|
||||
currency: '$',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2, minW: 2 },
|
||||
options: {
|
||||
format: 'money',
|
||||
value: '150',
|
||||
currency: '$',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2, minW: 2 },
|
||||
options: {
|
||||
format: 'money',
|
||||
value: '150',
|
||||
currency: '$',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2, minW: 2 },
|
||||
options: {
|
||||
format: 'money',
|
||||
value: '150',
|
||||
currency: '$',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Blog',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2, minW: 2 },
|
||||
options: {
|
||||
format: 'money',
|
||||
value: '150',
|
||||
currency: '$',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
toggleFloat() {
|
||||
this.shouldFloat = !this.shouldFloat;
|
||||
}
|
||||
|
||||
@action onQueryParamsChanged(changedParams) {
|
||||
this.reloadDashboard.perform(changedParams);
|
||||
}
|
||||
|
||||
@task *reloadDashboard(params) {
|
||||
const { extension } = this.args.dashboard;
|
||||
const index = this.args.index;
|
||||
let dashboards = [];
|
||||
@action onChangeGrid(event) {
|
||||
console.log('Grid Stack event: ', event);
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
|
||||
try {
|
||||
dashboards = yield this.fetch.get(extension.fleetbase.dashboard, params, { namespace: '' });
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLoading = false;
|
||||
|
||||
if (isArray(dashboards)) {
|
||||
this.dashboard = dashboards.objectAt(index);
|
||||
}
|
||||
@action onDragToDashboard(event) {
|
||||
console.log('Grid Stack drag event: ', event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,37 @@
|
||||
</Overlay::Header>
|
||||
|
||||
<Overlay::Body @wrapperClass="new-service-rate-overlay-body px-4 space-y-4 pt-4" @increaseInnerBodyHeightBy={{1000}}>
|
||||
<GridStack @options={{hash float=true animate=true}} @onChange={{this.onChangeGrid}} @onSetupDragIn={{this.onDragToDashboard}} as |grid|>
|
||||
{{#each this.availableWidgets as |widget|}}
|
||||
<GridStackItem @options={{hash w=4 h=1}}>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800 shadow-sm mr-1"
|
||||
{{on "click" (fn this.addWidgetToDashboard widget)}}
|
||||
>
|
||||
<p class="text-lg font-bold dark:text-gray-100 text-black p-4">
|
||||
{{widget.name}}
|
||||
widget
|
||||
</p>
|
||||
</div>
|
||||
</GridStackItem>
|
||||
{{/each}}
|
||||
</GridStack>
|
||||
|
||||
<div class="grid grid-cols-3 gap-1 text-xs dark:text-gray-100">
|
||||
<div class="grid grid-cols-2 lg:grid-cols-12 gap-4">
|
||||
{{#each this.widgets as |widget|}}
|
||||
{{component widget.options.component}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#each this.availableWidgets as |widget|}}
|
||||
<GridStackItem @options={{widget.gridOptions}}>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800 shadow-sm mr-1"
|
||||
{{on "click" (fn this.addWidgetToDashboard widget)}}
|
||||
>
|
||||
<p class="text-lg font-bold dark:text-gray-100 text-black p-4">
|
||||
{{widget.name}}
|
||||
widget
|
||||
</p>
|
||||
</div>
|
||||
</GridStackItem>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
</Overlay::Body>
|
||||
</Overlay>
|
||||
@@ -1,28 +1,20 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
export default class DashboardWidgetPanelComponent extends Component {
|
||||
@tracked isLoading = false;
|
||||
@tracked isOpen = false;
|
||||
@service universe;
|
||||
@tracked availableWidgets = [];
|
||||
|
||||
/**
|
||||
* Constructs the component and applies initial state.
|
||||
*/
|
||||
constructor() {
|
||||
constructor(owner, { dashboard }) {
|
||||
super(...arguments);
|
||||
|
||||
console.log(this.args);
|
||||
}
|
||||
|
||||
didReceiveArguments() {
|
||||
if (this.args.isOpen !== this.isOpen) {
|
||||
// Handle the change in isOpen here
|
||||
this.isOpen = this.args.isOpen;
|
||||
console.log('Parent isOpen changed:', this.isOpen);
|
||||
}
|
||||
this.availableWidgets = this.universe.getWidgets();
|
||||
this.dashboard = dashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,19 +25,15 @@ export default class DashboardWidgetPanelComponent extends Component {
|
||||
*/
|
||||
@action setOverlayContext(overlayContext) {
|
||||
this.context = overlayContext;
|
||||
console.log('Context: ', this.context, arguments);
|
||||
|
||||
if (typeof this.args.onLoad === 'function') {
|
||||
this.args.onLoad(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the widget changes.
|
||||
*
|
||||
* @action
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
@action save() {}
|
||||
@action addWidgetToDashboard(widget) {
|
||||
this.dashboard.addWidget(widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles cancel button press.
|
||||
@@ -54,11 +42,17 @@ export default class DashboardWidgetPanelComponent extends Component {
|
||||
* @returns {any}
|
||||
*/
|
||||
@action onPressCancel() {
|
||||
this.context.close();
|
||||
// return contextComponentCallback(this, 'onPressCancel', this.widget);
|
||||
}
|
||||
|
||||
get widgets() {
|
||||
console.log(this.universe.getWidgets());
|
||||
return this.universe.getWidgets();
|
||||
@action onDragToDashboard(item) {
|
||||
console.log('Event: ', item);
|
||||
}
|
||||
|
||||
myClone(event) {
|
||||
const el = event.target.cloneNode(true);
|
||||
el.setAttribute('gs-id', 'foo'); // TEST why clone element is not used directly on drop #2231
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,62 @@
|
||||
import DashboardCountComponent from '../components/dashboard/count';
|
||||
import FleetbaseBlogComponent from '../components/fleetbase-blog';
|
||||
import GithubCardComponent from '../components/github-card';
|
||||
|
||||
export function initialize(application) {
|
||||
const universe = application.lookup('service:universe');
|
||||
|
||||
universe.registerWidget({
|
||||
name: 'Fleetbase Blog',
|
||||
position: {},
|
||||
options: { component: FleetbaseBlogComponent },
|
||||
});
|
||||
const fleetOpsWidgets = [
|
||||
{
|
||||
name: 'Open Issues',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2 },
|
||||
options: {},
|
||||
},
|
||||
];
|
||||
|
||||
const storefrontWidgets = [
|
||||
{
|
||||
name: 'Total Products',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2 },
|
||||
options: {},
|
||||
},
|
||||
];
|
||||
|
||||
const iamWidgets = [
|
||||
{
|
||||
name: 'User count',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2 },
|
||||
options: {},
|
||||
},
|
||||
{
|
||||
name: 'Group count',
|
||||
component: DashboardCountComponent,
|
||||
gridOptions: { w: 2, h: 2 },
|
||||
options: {},
|
||||
},
|
||||
];
|
||||
|
||||
const availableWidgets = [
|
||||
{
|
||||
name: 'Fleetbase Blog',
|
||||
component: FleetbaseBlogComponent,
|
||||
gridOptions: { w: 8, h: 3 },
|
||||
options: {},
|
||||
},
|
||||
{
|
||||
name: 'Github Card',
|
||||
component: GithubCardComponent,
|
||||
gridOptions: { w: 4, h: 3 },
|
||||
options: {},
|
||||
},
|
||||
...fleetOpsWidgets,
|
||||
...storefrontWidgets,
|
||||
...iamWidgets,
|
||||
];
|
||||
|
||||
universe.registerWidgets(availableWidgets);
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
3
console/app/models/dashboard-widget.js
Normal file
3
console/app/models/dashboard-widget.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Model from '@ember-data/model';
|
||||
|
||||
export default class DashboardWidgetModel extends Model {}
|
||||
3
console/app/models/dashboard.js
Normal file
3
console/app/models/dashboard.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import Model from '@ember-data/model';
|
||||
|
||||
export default class DashboardModel extends Model {}
|
||||
@@ -1,10 +1,6 @@
|
||||
{{page-title "Dashboard"}}
|
||||
<Layout::Section::Body class="overflow-y-scroll h-full pt-6">
|
||||
<div class="console-home-container mx-auto h-screen space-y-4" {{increase-height-by 300}}>
|
||||
<div class="grid grid-cols-1 md:grid-cols-12 gap-4">
|
||||
<GithubCard class="lg:col-span-4" />
|
||||
<FleetbaseBlog class="lg:col-span-8" />
|
||||
</div>
|
||||
<Dashboard @sidebar={{this.sidebarContext}} />
|
||||
</div>
|
||||
</Layout::Section::Body>
|
||||
@@ -21,6 +21,7 @@
|
||||
"lint:hbs:fix": "ember-template-lint . --fix",
|
||||
"lint:js": "eslint . --cache",
|
||||
"lint:js:fix": "eslint . --fix",
|
||||
"postinstall": "patch-package",
|
||||
"start": "pnpm run prebuild && ember serve",
|
||||
"test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"",
|
||||
"test:ember": "ember test"
|
||||
@@ -29,7 +30,6 @@
|
||||
"@ember/legacy-built-in-components": "^0.4.1",
|
||||
"@fleetbase/ember-core": "link:../packages/ember-core",
|
||||
"@fleetbase/ember-ui": "link:../packages/ember-ui",
|
||||
"@fleetbase/fleetops-engine": "^0.3.8",
|
||||
"@fleetbase/leaflet-routing-machine": "^3.2.16",
|
||||
"@fortawesome/ember-fontawesome": "^0.4.1",
|
||||
"ember-changeset": "^4.1.2",
|
||||
@@ -45,7 +45,8 @@
|
||||
"ember-radio-button": "3.0.0-beta.1",
|
||||
"ember-tag-input": "^3.1.0",
|
||||
"fleetbase-extensions-indexer": "^0.0.4",
|
||||
"gridstack": "^10.0.1",
|
||||
"gridstack": "^7.2.2",
|
||||
"patch-package": "^8.0.0",
|
||||
"postcss-at-rules-variables": "^0.3.0",
|
||||
"postcss-custom-properties": "^12.1.9",
|
||||
"postcss-nth-list": "^1.0.2"
|
||||
|
||||
34
console/patches/ember-gridstack+4.0.0.patch
Normal file
34
console/patches/ember-gridstack+4.0.0.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
diff --git a/node_modules/ember-gridstack/addon/components/grid-stack.js b/node_modules/ember-gridstack/addon/components/grid-stack.js
|
||||
index fa51392..ed247af 100644
|
||||
--- a/node_modules/ember-gridstack/addon/components/grid-stack.js
|
||||
+++ b/node_modules/ember-gridstack/addon/components/grid-stack.js
|
||||
@@ -40,7 +40,7 @@ export const GRID_STACK_EVENTS = [
|
||||
'removed',
|
||||
'resizestart',
|
||||
'resize',
|
||||
- 'resizestop',
|
||||
+ 'resizestop'
|
||||
];
|
||||
|
||||
export default class GridStackComponent extends Component {
|
||||
@@ -52,6 +52,7 @@ export default class GridStackComponent extends Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.gridStackRegistry.registerGrid(this.guid, this);
|
||||
+
|
||||
}
|
||||
|
||||
get options() {
|
||||
@@ -93,6 +94,12 @@ export default class GridStackComponent extends Component {
|
||||
_createGridStack() {
|
||||
this.gridStack = GridStack.init({ ...this.options }, this.elm);
|
||||
|
||||
+ if(this.dragInOptions){
|
||||
+ const { selector, options } = this.dragInOptions
|
||||
+ console.log("Setup Drag in: ", this.dragInOptions)
|
||||
+ this.gridStack?.setupDragIn(selector, options);
|
||||
+ }
|
||||
+
|
||||
GRID_STACK_EVENTS.forEach((eventName) => {
|
||||
const action = this.args[`on${capitalize(eventName)}`];
|
||||
|
||||
292
console/pnpm-lock.yaml
generated
292
console/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
14
console/tests/unit/models/dashboard-test.js
Normal file
14
console/tests/unit/models/dashboard-test.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
import { setupTest } from '@fleetbase/console/tests/helpers';
|
||||
|
||||
module('Unit | Model | dashboard', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('dashboard', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
14
console/tests/unit/models/dashboard-widget-test.js
Normal file
14
console/tests/unit/models/dashboard-widget-test.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
import { setupTest } from '@fleetbase/console/tests/helpers';
|
||||
|
||||
module('Unit | Model | dashboard widget', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('dashboard-widget', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
Submodule packages/ember-ui updated: c8a3e31af3...25ad1beb6c
Reference in New Issue
Block a user