Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AppBuilder/core
Submodule core updated from 033d06 to c66267
3 changes: 2 additions & 1 deletion AppBuilder/platform/plugins/included/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import viewList from "./view_list/FNAbviewlist.js";
import viewTab from "./view_tab/FNAbviewtab.js";
import viewDetail from "./view_detail/FNAbviewdetail.js";

const AllPlugins = [viewTab, viewList];
const AllPlugins = [viewTab, viewList, viewDetail];

export default {
load: (AB) => {
Expand Down
138 changes: 138 additions & 0 deletions AppBuilder/platform/plugins/included/view_detail/FNAbviewdetail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import FNAbviewdetailComponent from "./FNAbviewdetailComponent.js";

// Detail view plugin: replaces the original ABViewDetail / ABViewDetailCore.
// All logic from both Core and platform is contained in this file.
export default function FNAbviewdetail({
ABViewContainer,
ABViewComponentPlugin,
}) {
const ABViewDetailComponent = FNAbviewdetailComponent({
ABViewComponentPlugin,
});

const ABViewDetailDefaults = {
key: "detail",
icon: "file-text-o",
labelKey: "Detail(plugin)",
};

const ABViewDetailPropertyComponentDefaults = {
dataviewID: null,
showLabel: true,
labelPosition: "left",
labelWidth: 120,
height: 0,
};

return class ABViewDetailPlugin extends ABViewContainer {
/**
* @param {obj} values key=>value hash of ABView values
* @param {ABApplication} application the application object this view is under
* @param {ABView} parent the ABView this view is a child of. (can be null)
*/
constructor(values, application, parent, defaultValues) {
super(
values,
application,
parent,
defaultValues ?? ABViewDetailDefaults
);
}

static getPluginType() {
return "view";
}

static getPluginKey() {
return this.common().key;
}

static common() {
return ABViewDetailDefaults;
}

static defaultValues() {
return ABViewDetailPropertyComponentDefaults;
}

/**
* @method fromValues()
* Initialize this object with the given set of values.
* @param {obj} values
*/
fromValues(values) {
super.fromValues(values);

this.settings.labelPosition =
this.settings.labelPosition ||
ABViewDetailPropertyComponentDefaults.labelPosition;

this.settings.showLabel = JSON.parse(
this.settings.showLabel != null
? this.settings.showLabel
: ABViewDetailPropertyComponentDefaults.showLabel
);

this.settings.labelWidth = parseInt(
this.settings.labelWidth ||
ABViewDetailPropertyComponentDefaults.labelWidth
);
this.settings.height = parseInt(
this.settings.height ??
ABViewDetailPropertyComponentDefaults.height
);
}

/**
* @method componentList
* Return the list of components available on this view to display in the editor.
*/
componentList() {
const viewsToAllow = ["label", "text"];
const allComponents = this.application.viewAll();
return allComponents.filter((c) =>
viewsToAllow.includes(c.common().key)
);
}

addFieldToDetail(field, yPosition) {
if (field == null) return;

const newView = field
.detailComponent()
.newInstance(this.application, this);
if (newView == null) return;

newView.settings = newView.settings ?? {};
newView.settings.fieldId = field.id;
newView.settings.labelWidth =
this.settings.labelWidth ||
ABViewDetailPropertyComponentDefaults.labelWidth;
newView.settings.alias = field.alias;
newView.position.y = yPosition;

this._views.push(newView);
return newView;
}

/**
* @method component()
* Return a UI component based upon this view.
* @return {obj} UI component
*/
component() {
return new ABViewDetailComponent(this);
}

warningsEval() {
super.warningsEval();

const DC = this.datacollection;
if (!DC) {
this.warningsMessage(
`can't resolve it's datacollection[${this.settings.dataviewID}]`
);
}
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export default function FNAbviewdetailComponent({
/*AB,*/
ABViewComponentPlugin,
}) {
return class ABAbviewdetailComponent extends ABViewComponentPlugin {
constructor(baseView, idBase, ids) {
super(
baseView,
idBase || `ABViewDetail_${baseView.id}`,
Object.assign({ detail: "" }, ids)
);
}

ui() {
const settings = this.settings;
const _uiDetail = {
id: this.ids.detail,
view: "dataview",
type: {
width: 1000,
height: 30,
},
template: (item) => {
if (!item) return "";
return JSON.stringify(item);
},
};

// set height or autoHeight
if (settings.height !== 0) _uiDetail.height = settings.height;
else _uiDetail.autoHeight = true;

const _ui = super.ui([_uiDetail]);

delete _ui.type;

return _ui;
}

async init(AB) {
await super.init(AB);

const dc = this.datacollection;

if (!dc) return;

// bind dc to component
dc.bind($$(this.ids.detail));
}
};
}
51 changes: 39 additions & 12 deletions test/AppBuilder/platform/views/ABViewDetail.test.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
import assert from "assert";
import ABFactory from "../../../../AppBuilder/ABFactory";
import ABViewDetail from "../../../../AppBuilder/platform/views/ABViewDetail";
import ABViewDetailComponent from "../../../../AppBuilder/platform/views/viewComponent/ABViewDetailComponent";
import ABViewContainer from "../../../../AppBuilder/platform/views/ABViewContainer";
import ABViewComponent from "../../../../AppBuilder/platform/views/viewComponent/ABViewComponent";

function getTarget() {
const AB = new ABFactory();
const application = AB.applicationNew({});
return new ABViewDetail({}, application);
}
describe("ABViewDetail plugin", function () {

describe("ABViewDetail widget", function () {
it(".component - should return a instance of ABViewDetailComponent", function () {
const target = getTarget();
let AB;
let application;
let viewDetail;

const result = target.component();
before(function () {
AB = new ABFactory();
// Only load plugins so "detail" is registered; skip full init() to avoid Network/socket.io in test env.
AB.pluginLocalLoad();
application = AB.applicationNew({});
viewDetail = application.viewNew({ key: "detail" }, application);
});

it("can pull a view from ABFactory given { key: 'detail' } values", function () {
assert.ok(viewDetail, "viewNew({ key: 'detail' }) should return a view");
});

it("the resulting object is a type of ABViewContainer class", function () {
assert.ok(
viewDetail instanceof ABViewContainer,
"Detail view should extend ABViewContainer"
);
});

it("the object has .component() method", function () {
assert.strictEqual(
typeof viewDetail.component,
"function",
"Detail view should have a .component() method"
);
});

assert.equal(true, result instanceof ABViewDetailComponent);
it(".component() returns an object of type ABViewComponent class", function () {
const result = viewDetail.component();
assert.ok(
result instanceof ABViewComponent,
".component() should return an instance of ABViewComponent"
);
});

});
Loading