add, remove, edit widgets

This commit is contained in:
Turtuvshin
2024-01-29 18:28:53 +08:00
parent 2e8a6de7ea
commit 6844e61dd4
11 changed files with 124 additions and 57 deletions

View File

@@ -7,6 +7,20 @@
"laravel"
],
"license": "MIT",
"repositories": [
{
"type": "path",
"url": "../packages/core-api"
},
{
"type": "path",
"url": "../packages/fleetops"
},
{
"type": "path",
"url": "../packages/storefront"
}
],
"require": {
"php": "^7.3|^8.0",
"fleetbase/core-api": "^1.3.6",

View File

@@ -1,8 +1,33 @@
<div class="fleetbase-dashboard-grid">
<div class="flex flex-row">
<Button @type="default" @icon="add" @helpText={{"Add new widgets to Dashbord"}} @onClick={{this.openWidgetSelector}} />
<div class="fleetbase-dashboard-grid flex items-center justify-between">
<div class="left-section">
<!-- Dashboard Title Text -->
<h1 class="text-lg font-bold">{{this.currentDashboard.name}}</h1>
</div>
<div class="right-section ml-4 flex items-center">
<!-- Select Dropdown -->
<div class="fleetbase-model-select fleetbase-power-select ember-model-select">
<PowerSelect
@options={{this.dashboards}}
@selected={{this.currentDashboard}}
@onChange={{fn (mut this.currentDashboard)}}
@placeholder="Select Dashboard"
@triggerClass="form-select form-input"
as |dashboard|
>
{{smart-humanize dashboard.name}}
</PowerSelect>
</div>
<!-- Button -->
<div class="ml-4 relative">
<Button @type="magic" @icon="edit" @helpText={{"Edit Dashboard"}} @onClick={{this.onChangeEdit}} />
<Button @type="magic" @icon="add" @helpText={{"Add new widgets to Dashboard"}} @onClick={{this.openWidgetSelector}} />
</div>
</div>
<Dashboard::Create @dashboard={{this.currentDashboard}} />
</div>
<Dashboard::WidgetPanel @isOpen={{this.isSelectingWidgets}} @onLoad={{this.setWidgetSelectorPanelContext}} @dashboard={{this.currentDashboard}} />
<Dashboard::Create @isEdit={{this.isEditDashboard}} @dashboard={{this.currentDashboard}} />
{{#if this.isSelectingWidgets}}
<Dashboard::WidgetPanel @isOpen={{this.isSelectingWidgets}} @onLoad={{this.setWidgetSelectorPanelContext}} @dashboard={{this.currentDashboard}} @onClose={{this.closeWidgetSelector}} />
{{/if}}

View File

@@ -10,10 +10,10 @@ export default class DashboardComponent extends Component {
@tracked dashboards = [];
@tracked currentDashboard;
@tracked isSelectingWidgets = false;
@tracked isEditDashboard = false;
constructor() {
super(...arguments);
console.log(arguments);
this.loadDashboards.perform();
}
@@ -22,14 +22,14 @@ export default class DashboardComponent extends Component {
try {
this.dashboards = yield this.store.findAll('dashboard');
const currentDashboard = this.dashboards[0];
console.log(currentDashboard);
if (this.dashboards.length > 0) {
const currentDashboard = this.dashboards[0];
currentDashboard.widgets = yield this.store.query('dashboard-widget', { params: { dashboard_uuid: currentDashboard.uuid } });
currentDashboard.widgets = yield this.store.query('dashboard-widget', { dashboard_uuid: currentDashboard.uuid });
this.currentDashboard = currentDashboard;
currentDashboard.widgets = yield this.store.query('dashboard-widget', { dashboard_uuid: currentDashboard.uuid });
this.currentDashboard = currentDashboard;
console.log('Current Dashboard: ', this.currentDashboard);
console.log('Current Dashboard: ', this.currentDashboard);
}
} catch (error) {
console.error('Error loading dashboards:', error);
}
@@ -47,4 +47,12 @@ export default class DashboardComponent extends Component {
@action openWidgetSelector() {
this.isSelectingWidgets = true;
}
@action closeWidgetSelector() {
this.isSelectingWidgets = false;
}
@action onChangeEdit() {
this.isEditDashboard = !this.isEditDashboard;
}
}

View File

@@ -1,12 +1,17 @@
<div class="fleetbase-dashboard-grid" ...attributes>
<GridStack
@options={{hash float=true animate=true acceptWidgets=true}}
@options={{hash float=true animate=true acceptWidgets=true alwaysShowResizeHandle=@isEdit}}
@onChange={{this.onChangeGrid}}
@dragInOptions={{hash selector="test" options=(hash appendTo="body" helper="clone")}}
>
{{#each this.dashboard.widgets as |widget index|}}
<GridStackItem @options={{widget.gridOptions}}>
{{#each this.args.dashboard.widgets as |widget index|}}
<GridStackItem @options={{widget.grid_options}} class="relative">
{{component widget.component options=widget.options}}
{{!-- {{#if this.isEdit}} --}}
<div class="absolute top-0 right-0">
<Button @type="default" @icon="trash" @onClick={{fn this.removeWidget widget}} />
</div>
{{!-- {{/if}} --}}
</GridStackItem>
{{/each}}
</GridStack>

View File

@@ -1,21 +1,17 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
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 {
@tracked dashboard;
constructor(owner, { dashboard }) {
constructor(owner, args) {
super(...arguments);
this.dashboard = dashboard;
console.log('Dashboard in Create: ', this.args.dashboard, dashboard);
const { dashboard } = args;
// Access the dashboard property from the arguments
this.dashboard = dashboard || this.args.dashboard;
console.log('Dashboard in Create: ', this.args.dashboard, args, dashboard);
}
@action
@@ -34,4 +30,9 @@ export default class DashboardCreateComponent extends Component {
@action onDragToDashboard(event) {
console.log('Grid Stack drag event: ', event);
}
@action removeWidget(widget) {
console.log('Removing widget: ', widget);
this.args.dashboard.removeWidget(widget.id);
}
}

View File

@@ -2,18 +2,19 @@
<Overlay::Header @title={{"Add widgets"}} @hideStatusDot={{true}} @titleWrapperClass="leading-5">
<div class="flex flex-1 justify-end">
<Button @icon={{"save"}} @type="primary" @text={{"Save Dashboard"}} @onClick={{this.save}} @wrapperClass="mr-2" />
<Button @type="default" @icon="times" @helpText={{"Add new widgets to Dashbord"}} @onClick={{this.onPressCancel}} />
<Button @type="default" @icon="times" @helpText={{"Add new widgets to Dashbord"}} @onClick={{this.onPressClose}} />
</div>
</Overlay::Header>
<Overlay::Body @wrapperClass="new-service-rate-overlay-body px-4 space-y-4 pt-4" @increaseInnerBodyHeightBy={{1000}}>
<div class="grid grid-cols-3 gap-1 text-xs dark:text-gray-100">
{{#each this.availableWidgets as |widget|}}
<GridStackItem @options={{widget.gridOptions}}>
<GridStackItem @options={{widget.grid_options}}>
<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)}}
>
{{log this.args}}
<p class="text-lg font-bold dark:text-gray-100 text-black p-4">
{{widget.name}}
widget

View File

@@ -6,7 +6,8 @@ import { action } from '@ember/object';
export default class DashboardWidgetPanelComponent extends Component {
@service universe;
@tracked availableWidgets = [];
@tracked dashboard;
@tracked isOpen = true;
/**
* Constructs the component and applies initial state.
*/
@@ -16,7 +17,7 @@ export default class DashboardWidgetPanelComponent extends Component {
this.availableWidgets = this.universe.getWidgets();
this.dashboard = dashboard;
console.log(this.dashboard, dashboard, arguments);
console.log(this.availableWidgets);
}
/**
@@ -34,21 +35,18 @@ export default class DashboardWidgetPanelComponent extends Component {
}
@action addWidgetToDashboard(widget) {
this.dashboard.addWidget(widget);
console.log('Adding widget to dashboard: ', widget);
this.args.dashboard.addWidget(widget);
}
/**
* Handles cancel button press.
*
* @action
* @returns {any}
*/
@action onPressCancel() {
this.context.close();
// return contextComponentCallback(this, 'onPressCancel', this.widget);
}
@action onDragToDashboard(item) {
console.log('Event: ', item);
@action onPressClose() {
this.isOpen = false;
console.log(this.args);
this.args.onClose();
}
}

View File

@@ -1,15 +1,11 @@
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');
const fleetOpsWidgets = [
{
name: 'Open Issues',
component: DashboardCountComponent,
gridOptions: { w: 2, h: 2 },
component: 'dashboard/count',
grid_options: { w: 2, h: 2 },
options: {},
},
];
@@ -17,8 +13,8 @@ export function initialize(application) {
const storefrontWidgets = [
{
name: 'Total Products',
component: DashboardCountComponent,
gridOptions: { w: 2, h: 2 },
component: 'dashboard/count',
grid_options: { w: 2, h: 2 },
options: {},
},
];
@@ -26,14 +22,14 @@ export function initialize(application) {
const iamWidgets = [
{
name: 'User count',
component: DashboardCountComponent,
gridOptions: { w: 2, h: 2 },
component: 'dashboard/count',
grid_options: { w: 2, h: 2 },
options: {},
},
{
name: 'Group count',
component: DashboardCountComponent,
gridOptions: { w: 2, h: 2 },
component: 'dashboard/count',
grid_options: { w: 2, h: 2 },
options: {},
},
];
@@ -41,14 +37,14 @@ export function initialize(application) {
const availableWidgets = [
{
name: 'Fleetbase Blog',
component: FleetbaseBlogComponent,
gridOptions: { w: 8, h: 3 },
component: 'fleetbase-blog',
grid_options: { w: 8, h: 3 },
options: {},
},
{
name: 'Github Card',
component: GithubCardComponent,
gridOptions: { w: 4, h: 3 },
component: 'github-card',
grid_options: { w: 4, h: 3 },
options: {},
},
...fleetOpsWidgets,

View File

@@ -9,11 +9,30 @@ export default class DashboardModel extends Model {
const owner = getOwner(this);
const store = owner.lookup('service:store');
// create widget model instance
const widgetRecord = store.createRecord('dashboard-widget', widget);
widgetRecord.dashboard = this;
widgetRecord.save().then((widgetRecord) => {
this.widgets.pushObject(widgetRecord);
});
}
removeWidget(widget) {
const owner = getOwner(this);
const store = owner.lookup('service:store');
const widgetRecord = store.peekRecord('dashboard-widget', widget);
if (widgetRecord) {
widgetRecord
.destroyRecord()
.then(() => {
this.widgets.removeObject(widgetRecord);
})
.catch((error) => {
console.error('Error removing widget:', error);
});
}
}
}