gy-foo
Version:
A library that contains all models for the gy-web-project.
881 lines (867 loc) • 29.5 kB
JavaScript
class IButton {
constructor(obj) {
this.icon = obj.icon ? obj.icon : '';
this.label = obj.label ? obj.label : '';
this.class = obj.class ? obj.class : '';
this.disabled = obj.disabled ? obj.disabled : false;
this.tooltip = obj.tooltip ? obj.tooltip : '';
this.tooltipPosition = obj.tooltipPosition ? obj.tooltipPosition : 'bottom';
}
}
/**
* Save modes for Occurrences
*/
var ModeFlags;
(function (ModeFlags) {
/**
* Add this new Occurrence to the Entity
*/
ModeFlags["ADD"] = "add";
/**
* This Occurrence is a Copy of another Occurrence
*/
ModeFlags["CPY"] = "cpy";
/**
* Delete this Occurrence from the Entity
*/
ModeFlags["DEL"] = "del";
})(ModeFlags || (ModeFlags = {}));
var FieldRight;
(function (FieldRight) {
FieldRight["ALL"] = "ALL";
FieldRight["RDO"] = "RDO";
FieldRight["DNY"] = "DNY";
})(FieldRight || (FieldRight = {}));
var FieldDisplay;
(function (FieldDisplay) {
FieldDisplay["INPUT"] = "INP";
FieldDisplay["CALENDAR"] = "CAL";
FieldDisplay["CHECKBOX"] = "CHK";
FieldDisplay["DROPDOWN"] = "DDL";
FieldDisplay["IOV"] = "IOV";
FieldDisplay["RADIOGROUP"] = "RAD";
FieldDisplay["TEXTAREA"] = "TXT";
})(FieldDisplay || (FieldDisplay = {}));
class Field {
constructor(field) {
if (field) {
Object.keys(field).forEach((key) => (this[key] = field[key]));
}
}
canRead(checkType, meta) {
const readRights = [FieldRight.RDO, FieldRight.ALL];
return meta && meta[checkType] ? readRights.includes(meta[checkType]) : readRights.includes(this[checkType]);
}
canReadWrite(checkType, meta) {
return meta && meta[checkType] ? meta[checkType] === FieldRight.ALL : this[checkType] === FieldRight.ALL;
}
displayIOVBez() {
return this.display === FieldDisplay.IOV && this.iov;
}
isIOVId() {
return this.iov && this.display !== FieldDisplay.IOV;
}
}
class Occurrence {
/**
* Creates a new Occrruence
* @param occ An Occrrence object or an object that looks like an Occurence
*/
constructor(occ, modeFlag) {
if (occ) {
if (occ instanceof Occurrence) {
this.pk = occ.getPk();
this.structure = occ.getStructure();
this.data = occ.getData() ? this.convertValues(occ.getData(), occ.getStructure()) : {};
this.meta = occ.getMeta() || {};
this.modified = occ.isModified();
this.locked = occ.isLocked();
}
else {
this.pk = occ.pk;
this.structure = occ.structure;
this.data = occ.data ? this.convertValues(occ.data, occ.structure) : {};
this.meta = occ.meta || {};
this.modified = occ.modified ? occ.modified : false;
this.locked = occ.locked ? occ.locked : false;
}
}
else {
this.pk = null;
this.data = {};
this.structure = {};
this.meta = {};
this.modified = false;
this.locked = false;
}
this.setMode(modeFlag);
}
/**
* Converts the SubEntities in data to Entities
* @param data data to convert
* @param structure structure of current occ
* @returns new data object
*/
convertValues(data, structure) {
for (const key of Object.keys(structure)) {
const value = data[key.toUpperCase()];
if (value) {
data[key.toUpperCase()] = new Entity(value.occs ? value : { occs: value, structure: structure[key.toUpperCase()] });
}
}
return data;
}
// ------------------------------------------------------------------------------------------------------
// Get Functions
// ------------------------------------------------------------------------------------------------------
/**
* Gets the pk of this Occurrence
*/
getPk() {
return this.pk;
}
/**
* Gets the structure of this Occurrence
*/
getStructure() {
return this.structure;
}
/**
* Gets the value of the given field
* @param field the name of the field
* @returns the value of the field
*/
getValue(field) {
return this.data[field.toUpperCase()];
}
/**
* Returns the Mode of this Occurrence. Possible values are: 'add', 'cpy', 'del' and '';
* @returns returns the mode of the occ (ModeFlags)
*/
getMode() {
return this.data._mode || '';
}
/**
* Gets the data of this Occurence
* @param col get data with or without collections. Default is true (all data).
*/
getData(col) {
return col === false
? Object.keys(this.data)
.filter((field) => !this.structure[field.toUpperCase()])
.reduce((prev, field) => Object.assign(prev, { [field]: this.data[field] }), {})
: this.data;
}
/**
* Gets the Subentity from this Occurrence
* @param name the name of the Subentity
* @returns returns the subEntity
*/
getSubEnt(name) {
if (!this.hasCollection(name)) {
return (this.data[name.toUpperCase()] = new Entity());
}
return this.data[name.toUpperCase()];
}
/**
* Gets the Occurences of the given SubEntity
* @param name the name of the Subentity
* @returns data from SubEntity
*/
getCollection(name) {
return this.data[name.toUpperCase()] ? this.data[name.toUpperCase()].occs : [];
}
/**
* Gets a list of all fields of this Occurrence
* @param col if true all Subentitys will be included in this list, default false
* @returns returns an array of all field Names
*/
getFields(col) {
return Object.keys(this.data).filter((value) => col || !this.structure[value.toUpperCase()]);
}
/**
* Has the Occurrence been modified?
* @param checkSubEnt check Subentities (default: true)
*/
isModified(checkSubEnt = true) {
return this.modified || (!checkSubEnt || !this.hasAnyCollection() ? this.modified : this.checkSubEntityModified());
}
/**
* is this occurence locked and can not be edited?
*/
isLocked() {
return this.locked;
}
/**
* Gets the structure of the given subentity
* @param name the name of the subentity
*/
getSubEntityStructure(name) {
return this.structure[name.toUpperCase()];
}
/**
* Gets the Meta informations of this occurence
* @param entity the name of a subentity, whose meta information should be read
*/
getMeta() {
return this.meta;
}
/**
* Gets the Meta informations of this occurence for the given entityname
* @param entity the name of a subentity, whose meta information should be read
*/
getMetaFieldList(entity) {
return this.meta[entity.toUpperCase()]
? this.meta[entity.toUpperCase()].reduce((acc, val) => Object.assign(acc, val), {}) || {}
: {};
}
/**
* Gets the Meta information for one field, if given
* @param field the name of the field
* @param entity the name of a subentity, where the field should be looked up
*/
getMetaField(field, entity) {
const fieldname = field.startsWith('_') ? field : field.toUpperCase();
const metaList = this.meta[entity.toUpperCase()]
? this.meta[entity.toUpperCase()].find((value) => {
return fieldname in value;
})
: undefined;
return metaList ? metaList[fieldname] : {};
}
// ------------------------------------------------------------------------------------------------------
// Set Functions
// ------------------------------------------------------------------------------------------------------
/**
* Sets the _mode value of this Occurrence
* @param mode boolean, that defines the mode. Add if this Occurrence should be added to the Database,
* cpy if this is a Copy of a Occurrrence and del if this Occurrence should be deleted in the DB.
* If missing, the _mode flag will be deleted.
* @param col set the mode for all subentitys.
*/
setMode(mode, col) {
if (mode) {
if (mode.del) {
this.data._mode = ModeFlags.DEL;
}
else if (mode.cpy) {
this.data._mode = ModeFlags.CPY;
}
else if (mode.add) {
this.data._mode = ModeFlags.ADD;
}
else if (this.data._mode) {
delete this.data._mode;
}
}
else if (this.data._mode) {
delete this.data._mode;
}
if (col) {
Object.keys(this.structure).forEach((subEnt) => {
if (this.data.hasOwnProperty(subEnt)) {
this.getCollection(subEnt).forEach((occ) => occ.setMode(mode, col));
}
});
}
}
/**
* sets the pk property
* @param pk pk that should be set
*/
addPk(pk) {
if (this.pk) {
return;
}
this.pk = pk;
}
/**
* Sets the given field on the given value
* @param field the name of the field
* @param value the new value
* @param isUserChange is this change a userChange and should set the modified Flag? (default: false)
*/
setValue(field, value, isUserChange = false) {
if (isUserChange && this.isLocked()) {
return;
}
if (!field.startsWith('_')) {
field = field.toUpperCase();
}
const undovalue = this.data[field];
this.data[field] = value;
if (isUserChange && undovalue != value) {
this.modified = true;
}
}
/**
* Sets the given list of fields on the given values
* @param values list of fields and values in the form {fieldname1: value1, fieldname2: value2, ...}
* @param isUserChange is this change a userChange and should set the modified Flag? (default: false)
*/
setValues(values, isUserChange = false) {
if (!values || (isUserChange && this.isLocked())) {
return;
}
Object.entries(values).forEach(([field, value]) => this.setValue(field, value, isUserChange && !this.modified));
this.data = this.convertValues(this.data, this.structure);
}
/**
* Changes all Occurrences of the given Subentity
* @param name name ot the subentity
* @param occs list of the new Occurences
*/
setCollection(name, occs) {
if (this.hasCollection(name.toUpperCase())) {
this.data[name.toUpperCase()].occs = occs;
}
else if (this.getSubEntityStructure(name)) {
this.data[name.toUpperCase()] = new Entity({ occs, structure: this.getSubEntityStructure(name) });
}
}
/**
* Sets the structure of this Occurrence
* @param value the new value of the structure
*/
setStructure(value) {
this.structure = Object.assign(this.structure, value);
}
/**
* Sets the modified flag
* @param modified occ is modified?
* @param setSubEntites should the modified flag be set also in the subentites?
*/
setModified(modified, setSubEntites = false) {
this.modified = modified;
if (setSubEntites) {
Object.keys(this.structure).forEach((entName) => {
this.getSubEnt(entName).setModified(modified, setSubEntites);
});
}
}
/**
* Sets the Meta information for one field
* @param field the name of the field
* @param entity the name of a subentity, where the field should be looked up
* @param value the new value of the definition
*/
setMetaField(field, entity, value) {
if (value) {
const fldvalue = new Field(value);
const fldname = field.toUpperCase();
const entityname = entity.toUpperCase();
if (!this.meta) {
this.meta = { [entityname]: [{ [fldname]: fldvalue }] };
}
else if (!this.meta[entityname]) {
this.meta[entityname] = [{ [fldname]: fldvalue }];
}
else {
const metaList = this.meta[entityname].find((fldlst) => fldname in fldlst);
if (!metaList) {
this.meta[entityname].push({ [fldname]: fldvalue });
}
else {
Object.assign(metaList[fldname], fldvalue);
}
}
}
}
/**
* Sets the Meta information for one entity
* @param entity the name of a subentity, whose meta information should be set
* @param values the new values of the definition
*/
setMetaFieldList(entity, values) {
if (values) {
const fldlsts = Array.isArray(values) ? values : [values];
const entityname = entity.toUpperCase();
if (!this.meta) {
this.meta = { [entityname]: fldlsts };
}
else if (!this.meta[entityname]) {
this.meta[entityname] = fldlsts;
}
else {
fldlsts.forEach((fldlst) => Object.entries(fldlst).forEach(([field, value]) => this.setMetaField(field, entity, value)));
}
}
}
/**
* Sets the Meta information
* @param metaValue the new values of the definition
*/
setMeta(metaValue) {
if (metaValue) {
if (!this.meta) {
this.meta = metaValue;
}
else {
Object.entries(metaValue).forEach(([entity, fieldlsts]) => {
this.setMetaFieldList(entity, fieldlsts);
});
}
}
}
// ------------------------------------------------------------------------------------------------------
// Copy Functions
// ------------------------------------------------------------------------------------------------------
/**
* Copies the given Occurrence into this Occurrence
* @param occ the Occurrence that should be copied
* @param cpy the Copy mode should be set
* @param isUserChange is this change a userChange and should set the modified Flag? (default: false)
*/
copy(occ, cpy, isUserChange = false) {
this.pk = occ.pk;
this.data = occ.data;
this.structure = occ.structure;
this.meta = occ.meta;
this.modified = isUserChange;
this.locked = false;
this.setMode({ cpy });
}
/**
* Makes a copy of this Occurrence into a new instance.
* @returns new Occurrence
*/
copyOccFlat() {
return new Occurrence({
pk: this.pk,
structure: this.structure,
meta: this.meta,
data: { _pk: this.data._pk, _hash: this.data._hash },
modified: this.modified,
});
}
// ------------------------------------------------------------------------------------------------------
// SubEntity/Structure Functions
// ------------------------------------------------------------------------------------------------------
/**
* Checks if this Occurrence has the given Subentity
* @param name the name of the Subentity
* @returns true or false
*/
hasCollection(name) {
return this.data[name.toUpperCase()];
}
/**
* Checks if the Occ is type OCC or COL
* @returns true or false
*/
hasAnyCollection() {
for (const subEnt of Object.keys(this.structure)) {
if (this.data.hasOwnProperty(subEnt)) {
return true;
}
}
return false;
}
/**
* Changes the given Subentity
* @param name the name of the Subentity
* @param SubEnt the new Entity
* @param isUserChange is this a users change (should modified flag been set) (default: false)
*/
changeSubEnt(name, SubEnt, isUserChange = false) {
this.data[name.toUpperCase()] = SubEnt;
if (isUserChange) {
this.getSubEnt(name).setModified(true, false);
}
}
// ------------------------------------------------------------------------------------------------------
// Delete Functions
// ------------------------------------------------------------------------------------------------------
/**
* Deletes a Subenetity from this Occurrence
* @param name name of the subentity
*/
deleteSubEnt(name) {
delete this.data[name.toUpperCase()];
}
/**
* Deletes a field from this Occurrence
* @param name name of field
*/
deleteValue(name) {
delete this.data[name.toUpperCase()];
}
// ------------------------------------------------------------------------------------------------------
// Check Functions
// ------------------------------------------------------------------------------------------------------
/**
* checks if some subentity is modified
*/
checkSubEntityModified() {
for (const entName of Object.keys(this.structure)) {
if (this.hasCollection(entName) && this.getSubEnt(entName).isModified()) {
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------------------
// Additional
// ------------------------------------------------------------------------------------------------------
/**
* Compares this Occurrence with the given Occ. First the PK will be compared and then the hash value.
* @param occ the second occ
*/
equals(occ) {
return this.getPk() === occ.getPk() && this.getValue('_hash') === occ.getValue('_hash');
}
/**
* Gets a string representation of this Occurrence. This is mainly for debug purpose.
*/
toString() {
return JSON.stringify({ pk: this.pk, _hash: this.data._hash });
}
}
class Entity {
constructor(entity, keepModes = true) {
if (entity) {
if (entity instanceof Entity) {
this.structure = entity.getStructure();
this.occs = this.convertOccurences(entity.getOccs(), keepModes) || [];
}
else {
this.structure = entity.structure;
this.occs = this.convertOccurences(entity.occs, keepModes) || [];
}
}
else {
this.structure = {};
this.occs = [];
}
}
/**
* Checks if entity has the structure of an entity
* @param entity entity to check
*/
static isEntity(entity) {
return entity && entity.occs ? true : false;
}
/**
* Gets the number of the Occurrences of this Entity
*/
getOccsLength() {
return this.occs.length;
}
/**
* Get all Occurences of this entity.
*/
getOccs() {
return this.occs;
}
/**
* Sets all Occurrences of the Entity to the given array.
* @param occs array of the new Occurrences
*/
setOccs(occs) {
this.occs = occs;
}
/**
* Checks if the given occurence is in this Entity
* @param pk the pk of the occurrence
*/
hasOcc(pk) {
return this.occs.find((occ) => occ.getPk() === pk) != null;
}
/**
* Sets the given Occurence on the given value. If pk is missing, the first Occurrence is set.
* @param occ the new Occurrence
* @param pk the pk of the Occurrence
*/
setOcc(occ, pk) {
if (pk) {
this.occs = this.occs.map((oldOcc) => {
if (oldOcc.getPk() === pk) {
return occ;
}
else {
return oldOcc;
}
});
}
else {
this.occs[0] = occ;
}
}
/**
* Gets the Occurrence with the given pk, if no pk is given it gets the first Occurence
* @param pk PK of the Occurrence
*/
getOcc(pk) {
if (pk) {
return this.occs.find((occ) => occ.getPk() === pk);
}
else {
let occ;
if (this.occs && this.occs.length > 0) {
occ = this.occs[0];
}
else {
occ = new Occurrence();
this.addOcc(occ);
}
return occ;
}
}
/**
* Gets the structure of the Entity
*/
getStructure() {
return this.structure;
}
/**
* Adds an Occurrence to the Entity
* @param occ the new Occurrence
* @param modeFlag decides, if the add mode should be set for occ
* @param isUserChange is that a User Change
* @returns the pk of the new Occ
*/
addOcc(occ, add, isUserChange) {
const addFlag = add !== undefined && add !== null ? add : true;
if (!occ) {
occ = new Occurrence();
}
occ.setMode({ add: addFlag });
if (isUserChange) {
occ.setModified(true, false);
}
if (!occ.getPk()) {
let pk = 'new_';
let index = 1;
this.occs.forEach((occ) => {
if (occ.getPk().substr(0, 4) === 'new_' && Number(occ.getPk().substr(4)) >= index) {
index = Number(occ.getPk().substr(4)) + 1;
}
});
pk += index;
occ.addPk(pk);
}
if (!occ.getStructure() || !Object.keys(occ.getStructure()).length) {
occ.setStructure(this.structure);
}
const occIndex = this.occs.findIndex((o) => o.getPk() === occ.getPk());
if (occIndex >= 0) {
this.occs[occIndex] = occ;
}
else {
this.occs.push(occ);
}
return occ.getPk();
}
/**
* Copys an Occurrence to the Entity
* @param pk pk of the occurrence that should be copied
* @param modeFlag decides, if the copy mode should be set for the new occ
* @param isUserChange is this a User Change?
* @returns the pk of the new Occ
*/
copyOcc(pk, cpy, isUserChange) {
let cpyFlag = cpy !== undefined && cpy !== null ? cpy : true;
const occ = this.getOcc(pk);
const addFlag = occ.getMode() === 'add';
if (addFlag) {
cpyFlag = false;
}
const copyCount = this.occs.filter((o) => o.getPk().search(new RegExp('^(?:copy_)?' + occ.getPk())) >= 0).length;
const copyOcc = new Occurrence({
pk: 'copy_' + occ.getPk() + '#' + copyCount,
data: Object.assign({}, occ.getData()),
structure: occ.getStructure(),
meta: occ.getMeta(),
}, { add: addFlag, cpy: cpyFlag });
if (isUserChange) {
occ.setModified(true, false);
}
this.occs.push(copyOcc);
return copyOcc.getPk();
}
/**
* Adds the Occurrences of an Entity to this Occurrences
* @param entity the Entity that should be added
*/
addEntity(entity) {
this.occs.push(...this.convertOccurences(entity.occs).filter((occ) => !this.hasOcc(occ.getPk())));
}
convertOccurences(occs, keepModes = true) {
return occs.map((occ) => {
return occ instanceof Occurrence
? occ
: new Occurrence(occ.pk ? occ : { pk: occ._pk, data: occ, structure: this.structure || {} }, keepModes
? {
add: (occ.data != null ? occ.data._mode : occ._mode) === ModeFlags.ADD,
cpy: (occ.data != null ? occ.data._mode : occ._mode) === ModeFlags.CPY,
del: (occ.data != null ? occ.data._mode : occ._mode) === ModeFlags.DEL,
}
: null);
});
}
/**
* Sets the modified flag for all occs in the entity
* @param modified occ is modified?
* @param setSubEntites should the modified flag be set also in the subentites? (default: false)
*/
setModified(modified, setSubEntites = false) {
for (const occ of this.getOccs()) {
occ.setModified(modified, setSubEntites);
}
}
/**
* Has the Entity been modified?
* @param checkSubEnt check Subentities (default: true)
*/
isModified(checkSubEnt = true) {
for (const occ of this.getOccs()) {
if (occ.isModified(checkSubEnt)) {
return true;
}
}
return false;
}
}
class EntityDef {
constructor(entityDef) {
if (entityDef instanceof EntityDef) {
this.fields = entityDef.getFields();
this.altdef = entityDef.getAltdef();
this.init = entityDef.getInitMode();
}
else {
this.fields = entityDef
? Object.entries(entityDef.fields)
.map(([fldname, fld]) => [fldname, new Field(fld)])
.reduce((fields, [fldname, fld]) => Object.assign(fields, { [fldname]: fld }), {})
: {};
this.altdef = entityDef ? entityDef.altdef || 0 : 0;
this.init = entityDef ? entityDef.init || 0 : 0;
}
}
/**
* Gets the fields of this Entity Definition
*/
getFields() {
return this.fields;
}
/**
* Get the given field from this Entity Definition
* @param fld the name of the field
*/
getField(fld) {
if (typeof fld === 'string') {
return this.fields ? this.fields[fld.toUpperCase()] : undefined;
}
else {
return undefined;
}
}
/**
* Get a list of all fields, that can be seen.
* @param type 'lst' for list views (table), 'occ' for detail views, empty for reading without filter
* @param write read and write rights are needed
* @returns an array with all fields that fits the rigths
*/
getFieldList(options) {
if (this.fields) {
let result = Object.entries(this.fields);
if (options.type) {
const checkType = 'ar_' + options.type;
if (options.write) {
result = result.filter(([fld, field]) => this.canReadWrite(fld, checkType, options.meta ? options.meta[fld] : undefined));
}
else {
result = result.filter(([fld, field]) => this.canRead(fld, checkType, options.meta ? options.meta[fld] : undefined));
}
}
return result.map(([fld, field]) => {
let bez = field.bez;
if (options.meta && options.meta[fld] && options.meta[fld].bez) {
bez = options.meta[fld].bez;
}
return { fld, bez };
});
}
else {
return [];
}
}
/**
* Checks if the altdef flag is set.
*/
getAltdef() {
return this.altdef != null ? this.altdef : 0;
}
/**
* Checks if the init flag is set.
*/
getInitMode() {
return this.init != null ? this.init : 0;
}
/**
* Checks if the given field can be seen in a list
* @param fld the name of the field
* @param field an alternative field definition
*/
listCanRead(fld, field) {
return this.canRead(fld, 'ar_lst', field);
}
canRead(fld, checkType, field) {
const defaultField = this.getField(fld);
return defaultField && defaultField.canRead(checkType, field);
}
canReadWrite(fld, checkType, field) {
const defaultField = this.getField(fld);
return defaultField && defaultField.canReadWrite(checkType, field);
}
}
const ModelsMap = {
ENTITY: Entity,
OCCURRENCE: Occurrence,
ENTITYDEF: EntityDef
};
/**
* Different types for sending request to the backend
*/
var AccessTypes;
(function (AccessTypes) {
/**
* List of occurences or Entity
*/
AccessTypes["LST"] = "lst";
/**
* one Occurence without any subentity
*/
AccessTypes["OCC"] = "occ";
/**
* occurence with all the subentites
*/
AccessTypes["COL"] = "col";
})(AccessTypes || (AccessTypes = {}));
/**
* modes for reading data
*/
var ReadModeFlags;
(function (ReadModeFlags) {
/**
* only non-retarded-read fields (default)
*/
ReadModeFlags["DEF"] = "DEF";
/**
* only retarded-read fields
*/
ReadModeFlags["RET"] = "RET";
/**
* all fields
*/
ReadModeFlags["ALL"] = "ALL";
})(ReadModeFlags || (ReadModeFlags = {}));
/*
* Public API Surface of gy-models
*/
/**
* Generated bundle index. Do not edit.
*/
export { AccessTypes, Entity, EntityDef, Field, FieldDisplay, IButton, ModeFlags, ModelsMap, Occurrence, ReadModeFlags };
//# sourceMappingURL=gy-foo.js.map