Sync changes v29.0.0 from IceHrmPro (https://icehrm.com/purchase-icehrmpro)

This commit is contained in:
Alan Cell
2021-04-05 18:52:23 +02:00
parent 1a3e468458
commit df554680c4
105 changed files with 8729 additions and 570 deletions

View File

@@ -3,13 +3,21 @@
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
import ReactModalAdapterBase from '../../../api/ReactModalAdapterBase';
/**
* ClientAdapter
*/
class ClientAdapter extends AdapterBase {
class ClientAdapter extends ReactModalAdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.fieldNameMap = {};
this.hiddenFields = {};
this.tableFields = {};
this.formOnlyFields = {};
}
getDataMapping() {
return [
'id',
@@ -30,6 +38,32 @@ class ClientAdapter extends AdapterBase {
];
}
getTableColumns() {
return [
{
title: 'Name',
dataIndex: 'name',
sorter: true,
},
{
title: 'Details',
dataIndex: 'details',
sorter: true,
},
{
title: 'Address',
dataIndex: 'address',
sorter: true,
},
{
title: 'Contact Number',
dataIndex: 'contact_number',
sorter: true,
}
];
}
getFormFields() {
if (this.showSave) {
return [

View File

@@ -1,6 +1,5 @@
import { CompanyStructureAdapter, CompanyGraphAdapter } from './lib';
import IceDataPipe from "../../../api/IceDataPipe";
import CustomFieldAdapter from "../../../api/ReactCustomFieldAdapter";
function init(data) {
@@ -9,6 +8,7 @@ function init(data) {
modJsList.tabCompanyStructure.setObjectTypeName('Company Structure');
modJsList.tabCompanyStructure.setDataPipe(new IceDataPipe(modJsList.tabCompanyStructure));
modJsList.tabCompanyStructure.setAccess(data.permissions.CompanyStructure);
modJsList.tabCompanyStructure.setCustomFields(data.customFields);
modJsList.tabCompanyGraph = new CompanyGraphAdapter('CompanyStructure');

View File

@@ -64,7 +64,7 @@ class CompanyStructureAdapter extends ReactModalAdapterBase {
}
getFormFields() {
return [
return this.addCustomFields([
['id', { label: 'ID', type: 'hidden', validation: '' }],
['title', { label: 'Name', type: 'text', validation: '' }],
['description', { label: 'Details', type: 'textarea', validation: '' }],
@@ -80,7 +80,7 @@ class CompanyStructureAdapter extends ReactModalAdapterBase {
['heads', {
label: 'Heads', type: 'select2multi', 'allow-null': true, 'remote-source': ['Employee', 'id', 'first_name+last_name'],
}],
];
]);
}
postRenderForm(object, $tempDomObj) {

View File

@@ -0,0 +1,18 @@
import { CommonCustomFieldAdapter } from './lib';
import IceDataPipe from '../../../api/IceDataPipe';
function init(data) {
const modJsList = {};
modJsList.tabCustomField = new CommonCustomFieldAdapter('CustomField', 'CustomField', {}, '');
modJsList.tabCustomField.setRemoteTable(true);
modJsList.tabCustomField.setObjectTypeName('Custom Field');
modJsList.tabCustomField.setDataPipe(new IceDataPipe(modJsList.tabCustomField));
modJsList.tabCustomField.setAccess(data.permissions.CustomField);
modJsList.tabCustomField.setTypes(data.types);
window.modJs = modJsList.tabCustomField;
window.modJsList = modJsList;
}
window.initAdminCustomFields = init;

View File

@@ -0,0 +1,166 @@
/**
* Author: Thilina Hasantha
*/
import ReactCustomFieldAdapter from '../../../api/ReactCustomFieldAdapter';
/**
* AssetTypeAdapter
*/
class CommonCustomFieldAdapter extends ReactCustomFieldAdapter {
getDataMapping() {
return [
'id',
'name',
'type',
'field_type',
'field_label',
'display',
'display_order',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Name' },
{ sTitle: 'Object Type' },
{ sTitle: 'Field Type' },
{ sTitle: 'Field Label' },
{ sTitle: 'Display Status' },
{ sTitle: 'Priority' },
];
}
getTableColumns() {
return [
{
title: 'Name',
dataIndex: 'name',
sorter: true,
},
{
title: 'Object Type',
dataIndex: 'type',
sorter: true,
},
{
title: 'Field Label',
dataIndex: 'field_label',
},
{
title: 'Field Type',
dataIndex: 'field_type',
},
{
title: 'Display Status',
dataIndex: 'display',
sorter: true,
},
{
title: 'Priority',
dataIndex: 'display_order',
sorter: true,
},
];
}
setTypes(tables) {
this.types = tables;
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['field_label', { label: 'Field Label', type: 'text', validation: '' }],
['type',
{
label: 'Object Type',
type: 'select2',
source: this.types,
},
],
['field_type', { label: 'Field Type', type: 'select', source: [['text', 'Text Field'], ['textarea', 'Text Area'], ['select', 'Select'], ['select2', 'Select2'], ['select2multi', 'Multi Select'], ['fileupload', 'File Upload'], ['date', 'Date'], ['datetime', 'Date Time'], ['time', 'Time'], ['signature', 'Signature']] }],
['field_validation', {
label: 'Validation', type: 'select2', validation: 'none', sort: 'none', 'null-label': 'Required', 'allow-null': true, source: [['none', 'None'], ['number', 'Number'], ['numberOrEmpty', 'Number or Empty'], ['float', 'Decimal'], ['email', 'Email'], ['emailOrEmpty', 'Email or Empty']],
}],
['field_options', {
label: 'Field Options',
type: 'datagroup',
form: [
['label', { label: 'Label', type: 'text', validation: '' }],
['value', { label: 'Value', type: 'text', validation: 'none' }],
],
html: '<div id="#_id_#" class="panel panel-default"><div class="panel-body">#_delete_##_edit_#<span style="color:#999;font-size:13px;font-weight:bold">#_label_#</span>:#_value_#</div></div>',
columns: [
{
title: 'Label',
dataIndex: 'label',
key: 'label',
},
{
title: 'Option Value',
dataIndex: 'value',
key: 'value',
},
],
validation: 'none',
}],
['display_order', { label: 'Priority', type: 'text', validation: 'none' }],
];
}
getFilters() {
return [
['type',
{
label: 'Object Type',
type: 'select2',
'allow-null': true,
source: this.types,
},
],
];
}
forceInjectValuesBeforeSave(params) {
const data = ['', {}];
const options = [];
let optionsData;
data[1].label = params.field_label;
data[1].type = params.field_type;
data[1].validation = params.field_validation;
if (['select', 'select2', 'select2multi'].indexOf(params.field_type) >= 0) {
optionsData = (params.field_options === '' || params.field_options === undefined)
? [] : JSON.parse(params.field_options);
for (const index in optionsData) {
options.push([optionsData[index].value, optionsData[index].label]);
}
data[1].source = options;
}
if (params.field_validation == null || params.field_validation === undefined) {
params.field_validation = '';
}
if (this.currentElement == null || this.currentElement.name == null || this.currentElement.name === '') {
params.name = this.getNameFromFieldName(params.field_label);
} else {
params.name = this.currentElement.name;
}
data[0] = params.name;
params.data = JSON.stringify(data);
params.display = 'Form';
params.display_order = parseInt(params.display_order);
if (!Number.isInteger(params.display_order)) {
params.display_order = 1;
}
return params;
}
}
module.exports = { CommonCustomFieldAdapter };

View File

@@ -98,6 +98,7 @@ class DashboardAdapter extends AdapterBase {
}
drawEmployeeDistributionChart() {
const that = this;
document.getElementById('EmployeeDistributionChart').style.display = 'none';
ReactDOM.render(
this.getSpinner(),
@@ -115,7 +116,7 @@ class DashboardAdapter extends AdapterBase {
forceFit: true,
title: {
visible: true,
text: 'Employee Distribution',
text: that.gt('Employee Distribution'),
},
description: {
visible: false,
@@ -125,7 +126,7 @@ class DashboardAdapter extends AdapterBase {
visible: true,
content: {
value: chartData.reduce((acc, item) => acc + item.value, 0),
name: 'Total',
name: that.gt('Total'),
},
},
legend: {
@@ -151,6 +152,7 @@ class DashboardAdapter extends AdapterBase {
}
drawOnlineOfflineEmployeeChart() {
const that = this;
document.getElementById('EmployeeOnlineOfflineChart').style.display = 'none';
ReactDOM.render(
this.getSpinner(),
@@ -168,7 +170,7 @@ class DashboardAdapter extends AdapterBase {
forceFit: true,
title: {
visible: true,
text: 'Employee Check-Ins',
text: that.gt('Employee Check-Ins'),
},
description: {
visible: false,
@@ -178,7 +180,7 @@ class DashboardAdapter extends AdapterBase {
visible: true,
content: {
value: chartData.reduce((acc, item) => acc + item.value, 0),
name: 'Total',
name: that.gt('Total'),
},
},
legend: {
@@ -199,6 +201,7 @@ class DashboardAdapter extends AdapterBase {
}
drawCompanyLeaveEntitlementChart() {
const that = this;
document.getElementById('CompanyLeaveEntitlementChart').style.display = 'none';
ReactDOM.render(
this.getSpinner(),
@@ -216,7 +219,7 @@ class DashboardAdapter extends AdapterBase {
forceFit: true,
title: {
visible: true,
text: 'Company Vacation Usage',
text: that.gt('Company Vacation Usage'),
},
description: {
visible: false,
@@ -226,7 +229,7 @@ class DashboardAdapter extends AdapterBase {
visible: true,
content: {
value: chartData.reduce((acc, item) => acc + item.value, 0),
name: 'Total',
name: that.gt('Total'),
},
},
legend: {

View File

@@ -34,6 +34,8 @@ class DocumentAdapter extends AdapterBase {
['expire_notification_month', { label: 'Notify Expiry Before One Month', type: 'select', source: [['Yes', 'Yes'], ['No', 'No']] }],
['expire_notification_week', { label: 'Notify Expiry Before One Week', type: 'select', source: [['Yes', 'Yes'], ['No', 'No']] }],
['expire_notification_day', { label: 'Notify Expiry Before One Day', type: 'select', source: [['Yes', 'Yes'], ['No', 'No']] }],
['share_with_employee', { label: 'Share with Employee', type: 'select', source: [['Yes', 'Yes'], ['No', 'No']] }],
// [ "sign", {"label":"Require Signature","type":"select","source":[["Yes","Yes"],["No","No"]]}],
// [ "sign", {"label":"Require Signature","type":"select","source":[["Yes","Yes"],["No","No"]]}],
// [ "sign_label", {"label":"Signature Description","type":"textarea","validation":"none"}],
['details', { label: 'Details', type: 'textarea', validation: 'none' }],
@@ -146,6 +148,7 @@ class EmployeeDocumentAdapter extends AdapterBase {
['date_added', { label: 'Date Added', type: 'date', validation: '' }],
['valid_until', { label: 'Valid Until', type: 'date', validation: 'none' }],
['status', { label: 'Status', type: 'select', source: [['Active', 'Active'], ['Inactive', 'Inactive'], ['Draft', 'Draft']] }],
['visible_to', { label: 'Visible To', type: 'select', source: [['Owner', 'Owner'], ['Manager', 'Manager'], ['Admin', 'Admin']] }],
['details', { label: 'Details', type: 'textarea', validation: 'none' }],
['attachment', { label: 'Attachment', type: 'fileupload', validation: '' }],
];

View File

@@ -363,28 +363,7 @@ class EmployeeAdapter extends ReactModalAdapterBase {
});
}
return this.addActualFields(steps, fields);
}
addActualFields(steps, fields) {
return steps.map((item) => {
item.fields = item.fields.reduce((acc, fieldName) => {
const field = fields.find(([name]) => name === fieldName);
if (field) {
acc.push(field);
}
return acc;
}, []);
return item;
});
}
getFormOptions() {
return {
width: 1024,
twoColumnLayout: false,
};
return this.addActualFieldsForStepModal(steps, fields);
}
getFilters() {

View File

@@ -344,7 +344,7 @@ class PayrollColumnAdapter extends AdapterBase {
['enabled', { label: 'Enabled', type: 'select', source: [['Yes', 'Yes'], ['No', 'No']] }],
['default_value', { label: 'Default Value', type: 'text', validation: '' }],
fucntionColumnList,
['function_type', { label: 'Function Type', type: 'select', source: [['Advanced', 'Advanced'], ['Simple', 'Simple']] }],
['function_type', { label: 'Function Type', type: 'select', source: [['Simple', 'Simple']] }],
['calculation_function', { label: 'Function', type: 'code', validation: 'none' }],
];
}

View File

@@ -3,13 +3,21 @@
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
import ReactModalAdapterBase from '../../../api/ReactModalAdapterBase';
/**
* ProjectAdapter
*/
class ProjectAdapter extends AdapterBase {
class ProjectAdapter extends ReactModalAdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.fieldNameMap = {};
this.hiddenFields = {};
this.tableFields = {};
this.formOnlyFields = {};
}
getDataMapping() {
return [
'id',
@@ -26,6 +34,21 @@ class ProjectAdapter extends AdapterBase {
];
}
getTableColumns() {
return [
{
title: 'Name',
dataIndex: 'name',
sorter: true,
},
{
title: 'Client',
dataIndex: 'client',
sorter: true,
}
];
}
getFormFields() {
if (this.showSave) {
return [
@@ -60,7 +83,15 @@ class ProjectAdapter extends AdapterBase {
*/
class EmployeeProjectAdapter extends AdapterBase {
class EmployeeProjectAdapter extends ReactModalAdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.fieldNameMap = {};
this.hiddenFields = {};
this.tableFields = {};
this.formOnlyFields = {};
}
getDataMapping() {
return [
'id',
@@ -77,6 +108,22 @@ class EmployeeProjectAdapter extends AdapterBase {
];
}
getTableColumns() {
return [
{
title: 'Employee',
dataIndex: 'employee',
sorter: true,
},
{
title: 'Project',
dataIndex: 'project',
sorter: true,
}
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],

View File

@@ -9,8 +9,6 @@ import TimeUtils from './TimeUtils';
import RequestCache from './RequestCache';
import SocialShare from './SocialShare';
const Aes = require('./Aes');
window.RequestCache = RequestCache;
window.SocialShare = SocialShare;

View File

@@ -104,16 +104,16 @@ class ApproveAdminAdapter extends LogViewAdapter {
getStatusOptionsData(currentStatus) {
const data = {};
if (currentStatus == 'Approved') {
if (currentStatus === 'Approved') {
} else if (currentStatus == 'Pending') {
} else if (currentStatus === 'Pending') {
data.Approved = 'Approved';
data.Rejected = 'Rejected';
} else if (currentStatus == 'Rejected') {
} else if (currentStatus === 'Rejected') {
} else if (currentStatus == 'Cancelled') {
} else if (currentStatus === 'Cancelled') {
} else if (currentStatus == 'Processing') {
} else if (currentStatus === 'Processing') {
} else {
data['Cancellation Requested'] = 'Cancellation Requested';

View File

@@ -37,7 +37,7 @@ class CustomFieldAdapter extends AdapterBase {
['id', { label: 'ID', type: 'hidden' }],
['name', { label: 'Name', type: 'text', validation: '' }],
['display', { label: 'Display Status', type: 'select', source: [['Form', 'Show'], ['Hidden', 'Hidden']] }],
['field_type', { label: 'Field Type', type: 'select', source: [['text', 'Text Field'], ['textarea', 'Text Area'], ['select', 'Select'], ['select2', 'Select2'], ['select2multi', 'Multi Select'], ['fileupload', 'File Upload'], ['date', 'Date'], ['datetime', 'Date Time'], ['time', 'Time']] }],
['field_type', { label: 'Field Type', type: 'select', source: [['text', 'Text Field'], ['textarea', 'Text Area'], ['select', 'Select'], ['select2', 'Select2'], ['select2multi', 'Multi Select'], ['fileupload', 'File Upload'], ['date', 'Date'], ['datetime', 'Date Time'], ['time', 'Time'], ['signature', 'Signature']] }],
['field_label', { label: 'Field Label', type: 'text', validation: '' }],
['field_validation', {
label: 'Validation', type: 'select2', validation: 'none', sort: 'none', 'null-label': 'Required', 'allow-null': true, source: [['none', 'None'], ['number', 'Number'], ['numberOrEmpty', 'Number or Empty'], ['float', 'Decimal'], ['email', 'Email'], ['emailOrEmpty', 'Email or Empty']],

View File

@@ -61,10 +61,10 @@ class ModuleBase {
}
/**
* Some browsers do not support sending JSON in get parameters. Set this to true to avoid sending JSON
* @method setNoJSONRequests
* @param val {Boolean}
*/
* Some browsers do not support sending JSON in get parameters. Set this to true to avoid sending JSON
* @method setNoJSONRequests
* @param val {Boolean}
*/
setNoJSONRequests(val) {
this.noJSONRequests = val;
}
@@ -79,12 +79,12 @@ class ModuleBase {
}
/**
* Check if the current user has a permission
* @method checkPermission
* @param permission {String}
* @example
* this.checkPermission("Upload/Delete Profile Image")
*/
* Check if the current user has a permission
* @method checkPermission
* @param permission {String}
* @example
* this.checkPermission("Upload/Delete Profile Image")
*/
checkPermission(permission) {
if (this.permissions[permission] === undefined || this.permissions[permission] == null || this.permissions[permission] === 'Yes') {
return 'Yes';
@@ -143,6 +143,7 @@ class ModuleBase {
gt(key) {
if (this.translations[key] === undefined || this.translations[key] === null) {
console.log("Tr:" + key);
return key;
}
return this.translations[key][0];
@@ -168,15 +169,15 @@ class ModuleBase {
}
/**
* If this method returned false the action buttons in data table for modules will not be displayed.
* Override this method in module lib.js to hide action buttons
* @method showActionButtons
* @param permission {String}
* @example
* EmployeeLeaveEntitlementAdapter.method('showActionButtons() {
* return false;
* }
*/
* If this method returned false the action buttons in data table for modules will not be displayed.
* Override this method in module lib.js to hide action buttons
* @method showActionButtons
* @param permission {String}
* @example
* EmployeeLeaveEntitlementAdapter.method('showActionButtons() {
* return false;
* }
*/
showActionButtons() {
return true;
}
@@ -201,30 +202,30 @@ class ModuleBase {
}
/**
* Get the current profile
* @method getCurrentProfile
* @returns Profile of the current user if the profile is not switched if not switched profile
*/
* Get the current profile
* @method getCurrentProfile
* @returns Profile of the current user if the profile is not switched if not switched profile
*/
getCurrentProfile() {
return this.currentProfile;
}
/**
* Retrive data required to create select boxes for add new /edit forms for a given module. This is called when loading the module
* @method initFieldMasterData
* @param callback {Function} call this once loading completed
* @param callback {Function} call this once all field loading completed. This indicate that the form can be displayed saftly
* @example
* ReportAdapter.method('renderForm(object) {
* var that = this;
* this.processFormFieldsWithObject(object);
* var cb = function(){
* that.super.renderForm(object);
* };
* this.initFieldMasterData(cb);
* }
*/
* Retrive data required to create select boxes for add new /edit forms for a given module. This is called when loading the module
* @method initFieldMasterData
* @param callback {Function} call this once loading completed
* @param callback {Function} call this once all field loading completed. This indicate that the form can be displayed saftly
* @example
* ReportAdapter.method('renderForm(object) {
* var that = this;
* this.processFormFieldsWithObject(object);
* var cb = function(){
* that.super.renderForm(object);
* };
* this.initFieldMasterData(cb);
* }
*/
initFieldMasterData(callback, loadAllCallback, loadAllCallbackData) {
this.fieldMasterData = {};
this.fieldMasterDataKeys = {};
@@ -321,26 +322,26 @@ class ModuleBase {
}
/**
* Pass true to this method after creating module JS object to open new/edit entry form for the module on a popup.
* @method setShowFormOnPopup
* @param val {Boolean}
* @example
* modJs.subModJsList['tabCandidateApplication'] = new CandidateApplicationAdapter('Application','CandidateApplication',{"candidate":data.id}
* modJs.subModJsList['tabCandidateApplication'].setShowFormOnPopup(true);
*/
* Pass true to this method after creating module JS object to open new/edit entry form for the module on a popup.
* @method setShowFormOnPopup
* @param val {Boolean}
* @example
* modJs.subModJsList['tabCandidateApplication'] = new CandidateApplicationAdapter('Application','CandidateApplication',{"candidate":data.id}
* modJs.subModJsList['tabCandidateApplication'].setShowFormOnPopup(true);
*/
setShowFormOnPopup(val) {
this.showFormOnPopup = val;
}
/**
* Set this to true to if you need the datatable to load data page by page instead of loading all data at once.
* @method setRemoteTable
* @param val {Boolean}
* @example
* modJs.subModJsList['tabCandidateApplication'] = new CandidateApplicationAdapter('Application','CandidateApplication',{"candidate":data.id}
* modJs.subModJsList['tabCandidateApplication'].setRemoteTable(true);
*/
* Set this to true to if you need the datatable to load data page by page instead of loading all data at once.
* @method setRemoteTable
* @param val {Boolean}
* @example
* modJs.subModJsList['tabCandidateApplication'] = new CandidateApplicationAdapter('Application','CandidateApplication',{"candidate":data.id}
* modJs.subModJsList['tabCandidateApplication'].setRemoteTable(true);
*/
setRemoteTable(val) {
this.createRemoteTable = val;
@@ -373,14 +374,14 @@ class ModuleBase {
}
if (this.fieldMasterDataCallback !== null
&& this.fieldMasterDataCallback !== undefined
&& this.isAllLoaded(this.fieldMasterDataKeys)
&& (this.fieldMasterDataCallbackData !== null && this.fieldMasterDataCallbackData !== undefined)
&& this.fieldMasterDataCallback !== undefined
&& this.isAllLoaded(this.fieldMasterDataKeys)
&& (this.fieldMasterDataCallbackData !== null && this.fieldMasterDataCallbackData !== undefined)
) {
this.fieldMasterDataCallback(this.fieldMasterDataCallbackData);
} else if (this.fieldMasterDataCallback !== null
&& this.fieldMasterDataCallback !== undefined
&& this.isAllLoaded(this.fieldMasterDataKeys)
&& this.fieldMasterDataCallback !== undefined
&& this.isAllLoaded(this.fieldMasterDataKeys)
) {
this.fieldMasterDataCallback();
}
@@ -598,10 +599,10 @@ class ModuleBase {
}
/**
* Create the data table on provided element id
* @method createTable
* @param val {Boolean}
*/
* Create the data table on provided element id
* @method createTable
* @param val {Boolean}
*/
createTable(elementId) {
const that = this;
@@ -679,10 +680,10 @@ class ModuleBase {
}
/**
* Create a data table on provided element id which loads data page by page
* @method createTableServer
* @param val {Boolean}
*/
* Create a data table on provided element id which loads data page by page
* @method createTableServer
* @param val {Boolean}
*/
createTableServer(elementId) {
const that = this;
@@ -749,10 +750,10 @@ class ModuleBase {
}
/**
* This should be overridden in module lib.js classes to return module headers which are used to create the data table.
* @method getHeaders
* @example
SettingAdapter.method('getHeaders() {
* This should be overridden in module lib.js classes to return module headers which are used to create the data table.
* @method getHeaders
* @example
SettingAdapter.method('getHeaders() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
@@ -760,17 +761,17 @@ class ModuleBase {
{ "sTitle": "Details"}
];
}
*/
*/
getHeaders() {
}
/**
* This should be overridden in module lib.js classes to return module field values which are used to create the data table.
* @method getDataMapping
* @example
SettingAdapter.method('getDataMapping() {
* This should be overridden in module lib.js classes to return module field values which are used to create the data table.
* @method getDataMapping
* @example
SettingAdapter.method('getDataMapping() {
return [
"id",
"name",
@@ -778,23 +779,23 @@ class ModuleBase {
"description"
];
}
*/
*/
getDataMapping() {
}
/**
* This should be overridden in module lib.js classes to return module from fields which are used to create the add/edit form and also used for initializing select box values in form.
* @method getFormFields
* @example
SettingAdapter.method('getFormFields() {
* This should be overridden in module lib.js classes to return module from fields which are used to create the add/edit form and also used for initializing select box values in form.
* @method getFormFields
* @example
SettingAdapter.method('getFormFields() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "value", {"label":"Value","type":"text","validation":"none"}]
];
}
*/
*/
getFormFields() {
}
@@ -808,26 +809,26 @@ class ModuleBase {
}
/**
* This can be overridden in module lib.js classes inorder to show a filter form
* @method getFilters
* @example
EmployeeAdapter.method('getFilters() {
* This can be overridden in module lib.js classes inorder to show a filter form
* @method getFilters
* @example
EmployeeAdapter.method('getFilters() {
return [
[ "job_title", {"label":"Job Title","type":"select2","allow-null":true,"null-label":"All Job Titles","remote-source":["JobTitle","id","name"]}],
[ "department", {"label":"Department","type":"select2","allow-null":true,"null-label":"All Departments","remote-source":["CompanyStructure","id","title"]}],
[ "supervisor", {"label":"Supervisor","type":"select2","allow-null":true,"null-label":"Anyone","remote-source":["Employee","id","first_name+last_name"]}]
];
}
*/
*/
getFilters() {
return null;
}
/**
* Show the edit form for an item
* @method edit
* @param id {int} id of the item to edit
*/
* Show the edit form for an item
* @method edit
* @param id {int} id of the item to edit
*/
edit(id) {
this.currentId = id;
this.getElement(id, []);
@@ -891,10 +892,10 @@ class ModuleBase {
}
/**
* Delete an item
* @method deleteRow
* @param id {int} id of the item to edit
*/
* Delete an item
* @method deleteRow
* @param id {int} id of the item to edit
*/
deleteRow(id) {
this.deleteParams.id = id;
@@ -903,17 +904,17 @@ class ModuleBase {
}
/**
* Show a popup with message
* @method showMessage
* @param title {String} title of the message box
* @param message {String} message
* @param closeCallback {Function} this will be called once the dialog is closed (optional)
* @param closeCallback {Function} data to pass to close callback (optional)
* @param closeCallbackData
* @param isPlain {Boolean} if true buttons are not shown (optional / default = true)
* @example
* this.showMessage("Error Occured while Applying Leave", callBackData);
*/
* Show a popup with message
* @method showMessage
* @param title {String} title of the message box
* @param message {String} message
* @param closeCallback {Function} this will be called once the dialog is closed (optional)
* @param closeCallback {Function} data to pass to close callback (optional)
* @param closeCallbackData
* @param isPlain {Boolean} if true buttons are not shown (optional / default = true)
* @example
* this.showMessage("Error Occured while Applying Leave", callBackData);
*/
showMessage(title, message, closeCallback = null, closeCallbackData = null, isPlain = false) {
const that = this;
let modelId = '';
@@ -1006,11 +1007,11 @@ class ModuleBase {
/**
* Create or edit an element
* @method save
* @param getFunctionCallBackData {Array} once a success is returned call get() function for this module with these parameters
* @param successCallback {Function} this will get called after success response
*/
* Create or edit an element
* @method save
* @param getFunctionCallBackData {Array} once a success is returned call get() function for this module with these parameters
* @param successCallback {Function} this will get called after success response
*/
save(callGetFunction, successCallback) {
const validator = new FormValidation(`${this.getTableName()}_submit`, true, { ShowPopup: false, LabelErrorClass: 'error' });
@@ -1041,7 +1042,7 @@ class ModuleBase {
const fields = this.getFormFields();
fields.forEach((field) => {
if ((field[1].type === 'date' || field[1].type === 'datetime')
&& (params[field[0]] === '' || params[field[0]] === '0000-00-00' || params[field[0]] === '0000-00-00 00:00:00')) {
&& (params[field[0]] === '' || params[field[0]] === '0000-00-00' || params[field[0]] === '0000-00-00 00:00:00')) {
if (field[1].validation === 'none') {
params[field[0]] = 'NULL';
} else {
@@ -1057,7 +1058,7 @@ class ModuleBase {
return this.gt('Password too short');
}
if (password.length > 20) {
if (password.length > 30) {
return this.gt('Password too long');
}
@@ -1085,23 +1086,23 @@ class ModuleBase {
}
/**
* Override this method to inject attitional parameters or modify existing parameters retrived from
* add/edit form before sending to the server
* @method forceInjectValuesBeforeSave
* @param params {Array} keys and values in form
* @returns {Array} modified parameters
*/
* Override this method to inject attitional parameters or modify existing parameters retrived from
* add/edit form before sending to the server
* @method forceInjectValuesBeforeSave
* @param params {Array} keys and values in form
* @returns {Array} modified parameters
*/
forceInjectValuesBeforeSave(params) {
return params;
}
/**
* Override this method to do custom validations at client side
* @method doCustomValidation
* @param params {Array} keys and values in form
* @returns {Null or String} return null if validation success, returns error message if unsuccessful
* @example
EmployeeLeaveAdapter.method('doCustomValidation(params) {
* Override this method to do custom validations at client side
* @method doCustomValidation
* @param params {Array} keys and values in form
* @returns {Null or String} return null if validation success, returns error message if unsuccessful
* @example
EmployeeLeaveAdapter.method('doCustomValidation(params) {
try{
if(params['date_start'] != params['date_end']){
var ds = new Date(params['date_start']);
@@ -1115,7 +1116,7 @@ class ModuleBase {
}
return null;
}
*/
*/
// eslint-disable-next-line no-unused-vars
doCustomValidation(params) {
return null;
@@ -1237,20 +1238,20 @@ class ModuleBase {
}
/**
* Override this method to do custom validations at client side for values selected in filters
* @method doCustomFilterValidation
* @param params {Array} keys and values in form
* @returns {Null or String} return null if validation success, returns error message if unsuccessful
*/
* Override this method to do custom validations at client side for values selected in filters
* @method doCustomFilterValidation
* @param params {Array} keys and values in form
* @returns {Null or String} return null if validation success, returns error message if unsuccessful
*/
doCustomFilterValidation(params) {
return true;
}
/**
* Reset selected filters
* @method resetFilters
*/
* Reset selected filters
* @method resetFilters
*/
resetFilters() {
this.filter = this.origFilter;
@@ -1351,20 +1352,20 @@ class ModuleBase {
/**
* Override this method in your module class to make changes to data fo the form before showing the form
* @method preRenderForm
* @param object {Array} keys value list for populating form
*/
* Override this method in your module class to make changes to data fo the form before showing the form
* @method preRenderForm
* @param object {Array} keys value list for populating form
*/
preRenderForm(object) {
}
/**
* Create the form
* @method renderForm
* @param object {Array} keys value list for populating form
*/
* Create the form
* @method renderForm
* @param object {Array} keys value list for populating form
*/
renderForm(object) {
const signatureIds = [];
@@ -1588,28 +1589,28 @@ class ModuleBase {
}
/**
* Override this method in your module class to make changes to data fo the form after showing it
* @method postRenderForm
* @param object {Array} keys value list for populating form
* @param $tempDomObj {DOM} a DOM element for the form
* @example
* UserAdapter.method('postRenderForm(object, $tempDomObj) {
* Override this method in your module class to make changes to data fo the form after showing it
* @method postRenderForm
* @param object {Array} keys value list for populating form
* @param $tempDomObj {DOM} a DOM element for the form
* @example
* UserAdapter.method('postRenderForm(object, $tempDomObj) {
if(object == null || object == undefined){
$tempDomObj.find("#changePasswordBtn").remove();
}
}
*/
*/
postRenderForm(object, $tempDomObj) {
}
/**
* Convert data group field to HTML
* @method dataGroupToHtml
* @param val {String} value in the field
* @param field {Array} field meta data
*/
* Convert data group field to HTML
* @method dataGroupToHtml
* @param val {String} value in the field
* @param field {Array} field meta data
*/
dataGroupToHtml(val, field) {
const data = JSON.parse(val);
@@ -1664,10 +1665,10 @@ class ModuleBase {
}
/**
* Reset the DataGroup for a given field
* @method resetDataGroup
* @param field {Array} field meta data
*/
* Reset the DataGroup for a given field
* @method resetDataGroup
* @param field {Array} field meta data
*/
resetDataGroup(field) {
$(`#${field[0]}`).val('');
$(`#${field[0]}_div`).html('');
@@ -2061,12 +2062,12 @@ class ModuleBase {
/**
* Fill a form with required values after showing it
* @method fillForm
* @param object {Array} form data
* @param formId {String} id of the form
* @param formId {Array} field meta data
*/
* Fill a form with required values after showing it
* @method fillForm
* @param object {Array} form data
* @param formId {String} id of the form
* @param formId {Array} field meta data
*/
fillForm(object, formId, fields) {
let placeHolderVal;
@@ -2180,7 +2181,7 @@ class ModuleBase {
}
} else if (fields[i][1].type === 'signature') {
if (object[fields[i][0]] !== '' || object[fields[i][0]] !== undefined
|| object[fields[i][0]] != null) {
|| object[fields[i][0]] != null) {
$(`${formId} #${fields[i][0]}`).data('signaturePad').fromDataURL(object[fields[i][0]]);
}
} else if (fields[i][1].type === 'simplemde') {
@@ -2197,9 +2198,9 @@ class ModuleBase {
}
/**
* Cancel edit or add new on modules
* @method cancel
*/
* Cancel edit or add new on modules
* @method cancel
*/
cancel() {
$(`#${this.getTableName()}Form`).hide();
@@ -2422,49 +2423,49 @@ class ModuleBase {
}
/**
* Override this method to change add new button label
* @method getAddNewLabel
*/
* Override this method to change add new button label
* @method getAddNewLabel
*/
getAddNewLabel() {
return 'Add New';
}
/**
* Used to set whether to show the add new button for a module
* @method setShowAddNew
* @param showAddNew {Boolean} value
*/
* Used to set whether to show the add new button for a module
* @method setShowAddNew
* @param showAddNew {Boolean} value
*/
setShowAddNew(showAddNew) {
this.showAddNew = showAddNew;
}
/**
* Used to set whether to show delete button for each entry in module
* @method setShowDelete
* @param val {Boolean} value
*/
* Used to set whether to show delete button for each entry in module
* @method setShowDelete
* @param val {Boolean} value
*/
setShowDelete(val) {
this.showDelete = val;
}
/**
* Used to set whether to show edit button for each entry in module
* @method setShowEdit
* @param val {Boolean} value
*/
* Used to set whether to show edit button for each entry in module
* @method setShowEdit
* @param val {Boolean} value
*/
setShowEdit(val) {
this.showEdit = val;
}
/**
* Used to set whether to show save button in form
* @method setShowSave
* @param val {Boolean} value
*/
* Used to set whether to show save button in form
* @method setShowSave
* @param val {Boolean} value
*/
setShowSave(val) {
@@ -2473,20 +2474,20 @@ class ModuleBase {
/**
* Used to set whether to show cancel button in form
* @method setShowCancel
* @param val {Boolean} value
*/
* Used to set whether to show cancel button in form
* @method setShowCancel
* @param val {Boolean} value
*/
setShowCancel(val) {
this.showCancel = val;
}
/**
* Datatable option array will be extended with associative array provided here
* @method getCustomTableParams
* @param val {Boolean} value
*/
* Datatable option array will be extended with associative array provided here
* @method getCustomTableParams
* @param val {Boolean} value
*/
getCustomTableParams() {
@@ -2499,12 +2500,12 @@ class ModuleBase {
/**
* This return html for action buttons in each row. Override this method if you need to make changes to action buttons.
* @method getActionButtonsHtml
* @param id {int} id of the row
* @param data {Array} data for the row
* @returns {String} html for action buttons
*/
* This return html for action buttons in each row. Override this method if you need to make changes to action buttons.
* @method getActionButtonsHtml
* @param id {int} id of the row
* @param data {Array} data for the row
* @returns {String} html for action buttons
*/
getActionButtonsHtml(id, data) {
const editButton = '<img class="tableActionButton" src="_BASE_images/edit.png" style="cursor:pointer;" rel="tooltip" title="Edit" onclick="modJs.edit(_id_);return false;"></img>';
@@ -2537,11 +2538,11 @@ class ModuleBase {
/**
* Generates a random string
* @method generateRandom
* @param length {int} required length of the string
* @returns {String} random string
*/
* Generates a random string
* @method generateRandom
* @param length {int} required length of the string
* @returns {String} random string
*/
generateRandom(length) {
const d = new Date();
@@ -2602,10 +2603,10 @@ class ModuleBase {
}
/**
* Override this method in a module to provide the help link for the module. Help link of the module on frontend will get updated with this.
* @method getHelpLink
* @returns {String} help link
*/
* Override this method in a module to provide the help link for the module. Help link of the module on frontend will get updated with this.
* @method getHelpLink
* @returns {String} help link
*/
getHelpLink() {
return null;

View File

@@ -0,0 +1,134 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
/**
* ReactApproveAdminAdapter
*/
import React from 'react';
import ReactLogViewAdapter from './ReactLogViewAdapter';
import {Space, Tag} from "antd";
import {CopyOutlined, DeleteOutlined, EditOutlined, MonitorOutlined} from "@ant-design/icons";
class ReactApproveAdminAdapter extends ReactLogViewAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
}
getStatusFieldPosition() {
const dm = this.getDataMapping();
return dm.length - 1;
}
openStatus(id, status) {
$(`#${this.itemNameLower}StatusModel`).modal('show');
$(`#${this.itemNameLower}_status`).html(this.getStatusOptions(status));
$(`#${this.itemNameLower}_status`).val(status);
this.statusChangeId = id;
}
closeDialog() {
$(`#${this.itemNameLower}StatusModel`).modal('hide');
}
changeStatus() {
const status = $(`#${this.itemNameLower}_status`).val();
const reason = $(`#${this.itemNameLower}_reason`).val();
if (status == undefined || status == null || status == '') {
this.showMessage('Error', `Please select ${this.itemNameLower} status`);
return;
}
const object = { id: this.statusChangeId, status, reason };
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'changeStatusSuccessCallBack';
callBackData.callBackFail = 'changeStatusFailCallBack';
this.customAction('changeStatus', `admin=${this.modulePathName}`, reqJson, callBackData);
this.closeDialog();
this.statusChangeId = null;
}
changeStatusSuccessCallBack(callBackData) {
this.showMessage('Successful', `${this.itemName} Request status changed successfully`);
this.get([]);
}
changeStatusFailCallBack(callBackData) {
this.showMessage('Error', `Error occurred while changing ${this.itemName} request status`);
}
getTableActionButtonJsx(adapter) {
return (text, record) => (
<Space size="middle">
{adapter.hasAccess('save') && adapter.showEdit
&& (
<Tag color="green" onClick={() => modJs.edit(record.id)} style={{ cursor: 'pointer' }}>
<EditOutlined />
{` ${adapter.gt('Edit')}`}
</Tag>
)}
{adapter.hasAccess('delete') && adapter.showDelete
&& (
<Tag color="volcano" onClick={() => modJs.deleteRow(record.id)} style={{ cursor: 'pointer' }}>
<DeleteOutlined />
{` ${adapter.gt('Delete')}`}
</Tag>
)}
{Object.keys(this.getStatusOptionsData(record.status)).length > 0
&& (
<Tag color="blue" onClick={() => modJs.openStatus(record.id, record.status)} style={{ cursor: 'pointer' }}>
<MonitorOutlined />
{` ${adapter.gt('Change Status')}`}
</Tag>
)}
<Tag color="cyan" onClick={() => modJs.getLogs(record.id)} style={{ cursor: 'pointer' }}>
<CopyOutlined />
{` ${adapter.gt('View Logs')}`}
</Tag>
</Space>
);
}
hasCustomButtons() {
return true;
}
isSubProfileTable() {
return this.user.user_level !== 'Admin' && this.user.user_level !== 'Restricted Admin';
}
getStatusOptionsData(currentStatus) {
const data = {};
if (currentStatus === 'Approved') {
} else if (currentStatus === 'Pending') {
data.Approved = 'Approved';
data.Rejected = 'Rejected';
} else if (currentStatus === 'Rejected') {
} else if (currentStatus === 'Cancelled') {
} else if (currentStatus === 'Processing') {
} else {
data['Cancellation Requested'] = 'Cancellation Requested';
data.Cancelled = 'Cancelled';
}
return data;
}
getStatusOptions(currentStatus) {
return this.generateOptions(this.getStatusOptionsData(currentStatus));
}
}
export default ReactApproveAdminAdapter;

View File

@@ -0,0 +1,71 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import React from 'react';
import { Space, Tag } from 'antd';
import {
CopyOutlined, DeleteOutlined, EditOutlined, MonitorOutlined,
} from '@ant-design/icons';
import ReactLogViewAdapter from './ReactLogViewAdapter';
class ReactApproveModuleAdapter extends ReactLogViewAdapter {
cancelRequest(id) {
const object = {};
object.id = id;
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'cancelSuccessCallBack';
callBackData.callBackFail = 'cancelFailCallBack';
this.customAction('cancel', `modules=${this.modulePathName}`, reqJson, callBackData);
}
// eslint-disable-next-line no-unused-vars
cancelSuccessCallBack(callBackData) {
this.showMessage('Successful', `${this.itemName} cancellation request sent`);
this.get([]);
}
cancelFailCallBack(callBackData) {
this.showMessage(`Error Occurred while cancelling ${this.itemName}`, callBackData);
}
getTableActionButtonJsx(adapter) {
return (text, record) => (
<Space size="middle">
{adapter.hasAccess('save') && adapter.showEdit
&& (
<Tag color="green" onClick={() => modJs.edit(record.id)} style={{ cursor: 'pointer' }}>
<EditOutlined />
{` ${adapter.gt('Edit')}`}
</Tag>
)}
{adapter.hasAccess('delete') && adapter.showDelete && record.status === 'Approved'
&& (
<Tag color="volcano" onClick={() => modJs.cancelRequest(record.id)} style={{ cursor: 'pointer' }}>
<DeleteOutlined />
{` ${adapter.gt('Cancel')}`}
</Tag>
)}
{adapter.hasAccess('delete') && adapter.showDelete && record.status === 'Pending'
&& this.user.user_level === 'Admin'
&& (
<Tag color="volcano" onClick={() => modJs.deleteRow(record.id)} style={{ cursor: 'pointer' }}>
<DeleteOutlined />
{` ${adapter.gt('Delete')}`}
</Tag>
)}
<Tag color="cyan" onClick={() => modJs.getLogs(record.id)} style={{ cursor: 'pointer' }}>
<CopyOutlined />
{` ${adapter.gt('View Logs')}`}
</Tag>
</Space>
);
}
}
export default ReactApproveModuleAdapter;

View File

@@ -20,6 +20,8 @@ class ReactCustomFieldAdapter extends AdapterBase {
return [
'id',
'name',
'field_type',
'field_label',
'display',
'display_order',
];
@@ -29,6 +31,8 @@ class ReactCustomFieldAdapter extends AdapterBase {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Name' },
{ sTitle: 'Field Type' },
{ sTitle: 'Field Label' },
{ sTitle: 'Display Status' },
{ sTitle: 'Priority' },
];
@@ -40,17 +44,24 @@ class ReactCustomFieldAdapter extends AdapterBase {
title: 'Name',
dataIndex: 'name',
sorter: true,
width: '25%',
},
{
title: 'Field Label',
dataIndex: 'field_label',
},
{
title: 'Field Type',
dataIndex: 'field_type',
},
{
title: 'Display Status',
dataIndex: 'display',
width: '35%',
sorter: true,
},
{
title: 'Priority',
dataIndex: 'display_order',
width: '10%',
sorter: true,
},
];
}
@@ -58,10 +69,8 @@ class ReactCustomFieldAdapter extends AdapterBase {
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['name', { label: 'Name', type: 'text', validation: '' }],
['display', { label: 'Display Status', type: 'select', source: [['Form', 'Show'], ['Hidden', 'Hidden']] }],
['field_type', { label: 'Field Type', type: 'select', source: [['text', 'Text Field'], ['textarea', 'Text Area'], ['select', 'Select'], ['select2', 'Select2'], ['select2multi', 'Multi Select'], ['fileupload', 'File Upload'], ['date', 'Date'], ['datetime', 'Date Time'], ['time', 'Time']] }],
['field_label', { label: 'Field Label', type: 'text', validation: '' }],
['field_type', { label: 'Field Type', type: 'select', source: [['text', 'Text Field'], ['textarea', 'Text Area'], ['select', 'Select'], ['select2', 'Select2'], ['select2multi', 'Multi Select'], ['fileupload', 'File Upload'], ['date', 'Date'], ['datetime', 'Date Time'], ['time', 'Time'], ['signature', 'Signature']] }],
['field_validation', {
label: 'Validation', type: 'select2', validation: 'none', sort: 'none', 'null-label': 'Required', 'allow-null': true, source: [['none', 'None'], ['number', 'Number'], ['numberOrEmpty', 'Number or Empty'], ['float', 'Decimal'], ['email', 'Email'], ['emailOrEmpty', 'Email or Empty']],
}],
@@ -87,11 +96,14 @@ class ReactCustomFieldAdapter extends AdapterBase {
],
validation: 'none',
}],
['display_order', { label: 'Priority', type: 'text', validation: 'number' }],
['display_section', { label: 'Display Section', type: 'text', validation: 'none' }],
['display_order', { label: 'Priority', type: 'text', validation: 'none' }],
];
}
getNameFromFieldName(fieldName) {
return fieldName.replace(/[^a-z0-9+]+/gi, '').toLowerCase();
}
setTableType(type) {
this.tableType = type;
}
@@ -102,18 +114,26 @@ class ReactCustomFieldAdapter extends AdapterBase {
return str != null && name.test(str);
};
if (this.currentElement == null || this.currentElement.name == null || this.currentElement.name === '') {
params.name = this.getNameFromFieldName(params.field_label);
if (!validateName(params.name)) {
return 'Invalid field label for custom field';
}
} else {
params.name = this.currentElement.name;
}
if (!validateName(params.name)) {
return 'Invalid name for custom field';
}
return null;
}
forceInjectValuesBeforeSave(params) {
const data = [params.name]; const options = []; let
optionsData;
data.push({});
const data = ['', {}];
const options = [];
let optionsData;
data[1].label = params.field_label;
data[1].type = params.field_type;
data[1].validation = params.field_validation;
@@ -128,8 +148,23 @@ class ReactCustomFieldAdapter extends AdapterBase {
if (params.field_validation == null || params.field_validation === undefined) {
params.field_validation = '';
}
params.data = JSON.stringify(data);
params.type = this.tableType;
if (this.currentElement == null || this.currentElement.name == null || this.currentElement.name === '') {
params.name = this.getNameFromFieldName(params.field_label);
} else {
params.name = this.currentElement.name;
}
data[0] = params.name;
params.data = JSON.stringify(data);
params.display = 'Form';
params.display_order = parseInt(params.display_order);
if (!Number.isInteger(params.display_order)) {
params.display_order = 1;
}
return params;
}
}

View File

@@ -0,0 +1,45 @@
import ReactModalAdapterBase from './ReactModalAdapterBase';
class ReactIdNameAdapter extends ReactModalAdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
}
getDataMapping() {
return [
'id',
'name',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Name' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['name', { label: 'Name', type: 'text', validation: '' }],
];
}
getTableColumns() {
return [
{
title: 'Id',
dataIndex: 'id',
sorter: true,
},
{
title: 'Name',
dataIndex: 'name',
sorter: true,
},
];
}
}
export default ReactIdNameAdapter;

View File

@@ -0,0 +1,58 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
/* global timeUtils */
/**
* ReactLogViewAdapter
*/
import ReactModalAdapterBase from './ReactModalAdapterBase';
class ReactLogViewAdapter extends ReactModalAdapterBase {
getLogs(id) {
const object = { id };
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'getLogsSuccessCallBack';
callBackData.callBackFail = 'getLogsFailCallBack';
this.customAction('getLogs', `admin=${this.modulePathName}`, reqJson, callBackData);
}
getLogsSuccessCallBack(callBackData) {
let tableLog = '<table class="table table-condensed table-bordered table-striped" style="font-size:14px;"><thead><tr><th>Notes</th></tr></thead><tbody>_days_</tbody></table> ';
const rowLog = '<tr><td><span class="logTime label label-default">_date_</span>&nbsp;&nbsp;<b>_status_</b><br/>_note_</td></tr>';
const logs = callBackData.data;
let html = '';
let rowsLogs = '';
for (let i = 0; i < logs.length; i++) {
let trow = rowLog;
trow = trow.replace(/_date_/g, logs[i].time);
trow = trow.replace(/_status_/g, `${logs[i].status_from} -> ${logs[i].status_to}`);
trow = trow.replace(/_note_/g, logs[i].note);
rowsLogs += trow;
}
if (rowsLogs !== '') {
tableLog = tableLog.replace('_days_', rowsLogs);
html += tableLog;
}
this.showMessage('Logs', html);
timeUtils.convertToRelativeTime($('.logTime'));
}
// eslint-disable-next-line no-unused-vars
getLogsFailCallBack(callBackData) {
this.showMessage('Error', 'Error occured while getting data');
}
}
export default ReactLogViewAdapter;

View File

@@ -48,6 +48,10 @@ class ReactModalAdapterBase extends AdapterBase {
return this.access.indexOf(type) > 0;
}
hasCustomButtons() {
return false;
}
initTable() {
if (this.tableInitialized) {
return false;
@@ -56,7 +60,11 @@ class ReactModalAdapterBase extends AdapterBase {
if (tableDom) {
this.tableContainer = React.createRef();
let columns = this.getTableColumns();
if (this.hasAccess('save') || this.hasAccess('delete') || this.hasAccess('element')) {
if (this.hasAccess('save')
|| this.hasAccess('delete')
|| this.hasAccess('element')
|| this.hasCustomButtons()
) {
columns.push({
title: 'Actions',
key: 'actions',
@@ -257,6 +265,27 @@ class ReactModalAdapterBase extends AdapterBase {
showLoader() {
// $('#iceloader').show();
}
addActualFieldsForStepModal(steps, fields) {
return steps.map((item) => {
item.fields = item.fields.reduce((acc, fieldName) => {
const field = fields.find(([name]) => name === fieldName);
if (field) {
acc.push(field);
}
return acc;
}, []);
return item;
});
}
getFormOptions() {
return {
width: 1024,
twoColumnLayout: false,
};
}
}
export default ReactModalAdapterBase;

View File

@@ -0,0 +1,70 @@
import React, { useState, useRef, useEffect } from "react";
import { SketchPicker } from 'react-color';
function useComponentVisible(initialIsVisible) {
const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
const ref = useRef(null);
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
setIsComponentVisible(false);
}
};
useEffect(() => {
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('click', handleClickOutside, true);
};
});
return { ref, isComponentVisible, setIsComponentVisible };
}
function IceColorPick(props) {
const { value, onChange, readOnly } = props;
const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(true);
const [color, setColor] = useState(value || '#FFF');
const [showPicker, setShowPicker] = useState(false);
useEffect(() => {
if (!isComponentVisible) {
setShowPicker(false);
}
}, [isComponentVisible])
useEffect(() => {
if (value) {
setColor(value);
}
}, [value]);
return <div className="colorpicker-container">
<div
className="colorpicker-preview"
onClick={() => {
if (!showPicker) {
setIsComponentVisible(true);
}
setShowPicker(!showPicker);
}}
style={ { backgroundColor: color} }
/>
<div ref={ref} className={`colorpicker-component ${(readOnly || !showPicker) ? 'hidden': ''}` }>
<SketchPicker
color={color}
disableAlpha
presetColors={[]}
onChangeComplete={({ hex }) => {
onChange(hex);
setColor(hex);
}}
/>
</div>
</div>;
}
export default IceColorPick;

View File

@@ -21,6 +21,7 @@ class IceDataGroup extends React.Component {
value = this.parseValue(value);
value = value.map(item => ({ ...item, key:item.id } ));
const columns = JSON.parse(JSON.stringify(field[1].columns));
if (!this.props.readOnly) {
columns.push({
title: 'Action',
@@ -30,6 +31,7 @@ class IceDataGroup extends React.Component {
),
});
}
return (
<>
{!this.props.readOnly &&

View File

@@ -7,6 +7,8 @@ import IceUpload from './IceUpload';
import IceDataGroup from './IceDataGroup';
import IceSelect from './IceSelect';
import IceLabel from './IceLabel';
import IceColorPick from './IceColorPick';
import IceSignature from './IceSignature';
const ValidationRules = {
@@ -86,24 +88,36 @@ class IceForm extends React.Component {
}
render() {
const { fields, twoColumnLayout } = this.props;
const { fields, twoColumnLayout, adapter } = this.props;
let formInputs = [];
const formInputs1 = [];
const formInputs2 = [];
const columns = !twoColumnLayout ? 1 : 2;
for (let i = 0; i < fields.length; i++) {
const formInput = this.createFromField(fields[i], this.props.viewOnly);
if (formInput != null) {
formInputs.push(
adapter.beforeRenderFieldHook(
fields[i][0],
this.createFromField(fields[i], this.props.viewOnly),
fields[i][1]
)
);
}
formInputs = formInputs.filter(input => !!input);
for (let i = 0; i < formInputs.length; i++) {
if (formInputs[i] != null) {
if (columns === 1) {
formInputs1.push(formInput);
formInputs1.push(formInputs[i]);
} else if (i % 2 === 0) {
formInputs1.push(formInput);
formInputs1.push(formInputs[i]);
} else {
formInputs2.push(formInput);
formInputs2.push(formInputs[i]);
}
}
}
const onFormLayoutChange = () => {};
const onFormLayoutChange = () => { };
return (
<Form
@@ -116,12 +130,12 @@ class IceForm extends React.Component {
size="middle"
>
{this.state.errorMsg
&& (
<>
<Alert message={this.state.errorMsg} type="error" showIcon />
<br />
</>
)}
&& (
<>
<Alert message={this.state.errorMsg} type="error" showIcon />
<br />
</>
)}
{columns === 1 && formInputs1}
{columns === 2 && (
<Row gutter={16}>
@@ -239,6 +253,9 @@ class IceForm extends React.Component {
</Form.Item>
);
} if (data.type === 'textarea') {
if (!data.rows) {
data.rows = 4;
}
return (
<Form.Item
labelCol={labelSpan}
@@ -249,7 +266,7 @@ class IceForm extends React.Component {
>
{viewOnly
? <IceLabel />
: <Input.TextArea />}
: <Input.TextArea rows={data.rows} />}
</Form.Item>
);
} if (data.type === 'date') {
@@ -355,6 +372,34 @@ class IceForm extends React.Component {
/>
</Form.Item>
);
} if (data.type === 'colorpick') {
return (
<Form.Item
labelCol={labelSpan}
name={name}
key={name}
label={data.label}
>
<IceColorPick
adapter={adapter}
field={field}
title={data.label}
readOnly={viewOnly}
/>
</Form.Item>
);
} if (data.type === 'signature') {
return (
<Form.Item
labelCol={labelSpan}
label={data.label}
key={name}
name={name}
rules={rules}
>
<IceSignature readOnly={viewOnly} />
</Form.Item>
);
}
return null;
}

View File

@@ -21,6 +21,7 @@ class IceFormModal extends React.Component {
}
show(data) {
this.props.adapter.beforeRenderFieldHook = this.props.adapter.beforeRenderField ? this.props.adapter.beforeRenderField(data) : (fieldName, field) => field;
if (!data) {
this.setState({ visible: true });
if (this.iceFormReference.current) {

View File

@@ -0,0 +1,83 @@
import React from 'react';
import SignatureCanvas from 'react-signature-canvas';
import { Button, Modal, Tag } from 'antd';
import { VerifiedOutlined } from '@ant-design/icons';
class IceSignature extends React.Component {
constructor(props) {
super(props);
this.onChange = props.onChange;
this.state = {
visible: false,
};
this.signature = React.createRef();
}
componentDidMount() {
}
show() {
this.setState({ visible: true });
}
setSignature(ref) {
if (ref == null) {
return;
}
const { value } = this.props;
if (value != null && value.length > 10) {
ref.fromDataURL(value);
}
}
hide() {
this.setState({ visible: false });
}
clear() {
this.signature.clear();
}
save() {
const data = this.signature.toDataURL('image/png');
this.onChange(data);
this.setState({ visible: false });
}
render() {
const { readOnly } = this.props;
return (
<>
<Modal
visible={this.state.visible}
title="Signature"
maskClosable={false}
centered
width={300}
onCancel={() => { this.hide(); }}
footer={[
<Button key="cancel" onClick={() => { this.hide(); }}>
Cancel
</Button>,
<Button key="clear" disabled={readOnly} type="dashed" onClick={() => { if (!readOnly) { this.clear(); } }}>
Clear
</Button>,
<Button key="ok" disabled={readOnly} type="primary" onClick={() => { if (!readOnly) { this.save(); } }}>
Submit
</Button>,
]}
>
<SignatureCanvas ref={(ref) => { this.signature = ref; this.setSignature(ref); }} canvasProps={{ width: 250, height: 200, className: 'sigCanvas', ...( readOnly ? { readOnly } : {}), }} />
</Modal>
<Tag color="blue" style={{ cursor: 'pointer' }} onClick={() => { this.show(); }}>
<VerifiedOutlined />
{' '}
Sign
</Tag>
</>
);
}
}
export default IceSignature;

View File

@@ -10,6 +10,7 @@ class IceStepFormModal extends IceFormModal {
}
show(data) {
this.props.adapter.beforeRenderFieldHook = this.props.adapter.beforeRenderField ? this.props.adapter.beforeRenderField(data) : (fieldName, field) => field;
if (!data) {
this.setState({ visible: true });
if (this.iceFormReference.current) {

View File

@@ -69,7 +69,6 @@ class IceTable extends React.Component {
};
search = (value) => {
console.log('search table:' + value);
this.setState({ search: value });
const fetchConfig = this.state.fetchConfig;
console.log(fetchConfig);
@@ -105,12 +104,10 @@ class IceTable extends React.Component {
}
fetch = (params = {}) => {
console.log('params:', params);
//this.setState({ loading: this.state.showLoading });
this.setState({ loading: true });
//const hideMessage = message.loading({ content: 'Loading Latest Data ...', key: 'loadingTable', duration: 1});
const pagination = { ...this.state.pagination };
console.log('pagination:', pagination);
if (this.props.adapter.localStorageEnabled) {
try {

View File

@@ -150,7 +150,7 @@ class UpdatePasswordModal extends React.Component {
return this.props.adapter.gt('Password too short');
}
if (password.length > 20) {
if (password.length > 30) {
return this.props.adapter.gt('Password too long');
}

View File

@@ -943,3 +943,73 @@ table.dataTable{
.table-row-dark {
background-color: #fbfbfb;
}
.mod-tab {
margin-bottom:0px;margin-left:5px;border-bottom: none;
}
.row {
margin-right: 0px;
margin-left: 0px;
}
.colorpicker-container {
}
.colorpicker-preview {
display: block;
width: 30px;
height: 30px;
border: 5px #FFF solid;
border-radius: 4px;
box-shadow: 0 0 6px 1px #c7c7c78f;
}
.colorpicker-component {
display: block;
position: absolute;
bottom: -10px;
left: 44px;
}
.dropdown-menu>li>a:hover {
background-color: #5ca4e7 i !important;
}
.sigCanvas {
border: 1px dashed;
}
.sigContainer {
width: 80%;
height: 80%;
margin: 0 auto;
background-color: #fff;
}
.sigPad {
width: 100%;
height: 100%;
}
.sigImage {
background-size: 200px 50px;
width: 200px;
height: 50px;
background-color: white;
}
.dropdown-menu>li>a:hover {
color: #000;
}
.ant-form-item-label>label {
position: relative;
display: inline-flex;
align-items: center;
height: auto !important;
color: rgba(0,0,0,.85);
font-size: 14px;
word-break: break-word;
white-space: break-spaces;
}

File diff suppressed because one or more lines are too long

8
web/dist/common.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -19430,16 +19430,16 @@ unlimitRow:function(a){var b=this.rowStructs[a];b.moreEls&&(b.moreEls.remove(),b
* Licensed MIT © Zeno Rocha
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var matches = require('matches-selector')
module.exports = function (element, selector, checkYoSelf) {
var parent = checkYoSelf ? element : element.parentNode
while (parent && parent !== document) {
if (matches(parent, selector)) return parent;
parent = parent.parentNode
}
}
var matches = require('matches-selector')
module.exports = function (element, selector, checkYoSelf) {
var parent = checkYoSelf ? element : element.parentNode
while (parent && parent !== document) {
if (matches(parent, selector)) return parent;
parent = parent.parentNode
}
}
},{"matches-selector":5}],2:[function(require,module,exports){
var closest = require('closest');
@@ -19636,45 +19636,45 @@ function listenSelector(selector, type, callback) {
module.exports = listen;
},{"./is":3,"delegate":2}],5:[function(require,module,exports){
/**
* Element prototype.
*/
var proto = Element.prototype;
/**
* Vendor function.
*/
var vendor = proto.matchesSelector
|| proto.webkitMatchesSelector
|| proto.mozMatchesSelector
|| proto.msMatchesSelector
|| proto.oMatchesSelector;
/**
* Expose `match()`.
*/
module.exports = match;
/**
* Match `el` to `selector`.
*
* @param {Element} el
* @param {String} selector
* @return {Boolean}
* @api public
*/
function match(el, selector) {
if (vendor) return vendor.call(el, selector);
var nodes = el.parentNode.querySelectorAll(selector);
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == el) return true;
}
return false;
/**
* Element prototype.
*/
var proto = Element.prototype;
/**
* Vendor function.
*/
var vendor = proto.matchesSelector
|| proto.webkitMatchesSelector
|| proto.mozMatchesSelector
|| proto.msMatchesSelector
|| proto.oMatchesSelector;
/**
* Expose `match()`.
*/
module.exports = match;
/**
* Match `el` to `selector`.
*
* @param {Element} el
* @param {String} selector
* @return {Boolean}
* @api public
*/
function match(el, selector) {
if (vendor) return vendor.call(el, selector);
var nodes = el.parentNode.querySelectorAll(selector);
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == el) return true;
}
return false;
}
},{}],6:[function(require,module,exports){
function select(element) {

View File

@@ -5,16 +5,16 @@
* Licensed MIT © Zeno Rocha
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var matches = require('matches-selector')
module.exports = function (element, selector, checkYoSelf) {
var parent = checkYoSelf ? element : element.parentNode
while (parent && parent !== document) {
if (matches(parent, selector)) return parent;
parent = parent.parentNode
}
}
var matches = require('matches-selector')
module.exports = function (element, selector, checkYoSelf) {
var parent = checkYoSelf ? element : element.parentNode
while (parent && parent !== document) {
if (matches(parent, selector)) return parent;
parent = parent.parentNode
}
}
},{"matches-selector":5}],2:[function(require,module,exports){
var closest = require('closest');
@@ -211,45 +211,45 @@ function listenSelector(selector, type, callback) {
module.exports = listen;
},{"./is":3,"delegate":2}],5:[function(require,module,exports){
/**
* Element prototype.
*/
var proto = Element.prototype;
/**
* Vendor function.
*/
var vendor = proto.matchesSelector
|| proto.webkitMatchesSelector
|| proto.mozMatchesSelector
|| proto.msMatchesSelector
|| proto.oMatchesSelector;
/**
* Expose `match()`.
*/
module.exports = match;
/**
* Match `el` to `selector`.
*
* @param {Element} el
* @param {String} selector
* @return {Boolean}
* @api public
*/
function match(el, selector) {
if (vendor) return vendor.call(el, selector);
var nodes = el.parentNode.querySelectorAll(selector);
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == el) return true;
}
return false;
/**
* Element prototype.
*/
var proto = Element.prototype;
/**
* Vendor function.
*/
var vendor = proto.matchesSelector
|| proto.webkitMatchesSelector
|| proto.mozMatchesSelector
|| proto.msMatchesSelector
|| proto.oMatchesSelector;
/**
* Expose `match()`.
*/
module.exports = match;
/**
* Match `el` to `selector`.
*
* @param {Element} el
* @param {String} selector
* @return {Boolean}
* @api public
*/
function match(el, selector) {
if (vendor) return vendor.call(el, selector);
var nodes = el.parentNode.querySelectorAll(selector);
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == el) return true;
}
return false;
}
},{}],6:[function(require,module,exports){
function select(element) {

View File

@@ -31,7 +31,7 @@ class EmployeeDocumentAdapter extends AdapterBase {
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['document', { label: 'Document', type: 'select2', 'remote-source': ['Document', 'id', 'name'] }],
['document', { label: 'Document', type: 'select2', 'remote-source': ['Document', 'id', 'name', 'getDocumentTypesForUser'] }],
// [ "date_added", {"label":"Date Added","type":"date","validation":""}],
['valid_until', { label: 'Valid Until', type: 'date', validation: 'none' }],
['status', { label: 'Status', type: 'select', source: [['Active', 'Active'], ['Inactive', 'Inactive'], ['Draft', 'Draft']] }],

56
web/package-lock.json generated
View File

@@ -290,6 +290,11 @@
"regenerator-runtime": "^0.13.4"
}
},
"@icons/material": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
"integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
},
"@types/d3-timer": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-1.0.10.tgz",
@@ -491,6 +496,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -499,6 +509,11 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"material-colors": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
},
"mini-store": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/mini-store/-/mini-store-3.0.6.tgz",
@@ -949,6 +964,20 @@
"prop-types": "^15.6.2"
}
},
"react-color": {
"version": "2.19.3",
"resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz",
"integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==",
"requires": {
"@icons/material": "^0.2.4",
"lodash": "^4.17.15",
"lodash-es": "^4.17.15",
"material-colors": "^1.2.1",
"prop-types": "^15.5.10",
"reactcss": "^1.2.0",
"tinycolor2": "^1.4.1"
}
},
"react-dom": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
@@ -970,6 +999,23 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-signature-canvas": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-signature-canvas/-/react-signature-canvas-1.0.3.tgz",
"integrity": "sha512-6KBZFWLgjbnV80hh0sYW4ZKLJkojktP+de+xrnBGjB6HBK2dOoYH3rVxjtCvpMhjM/e4cqgAoQVz3lYdKCgWxw==",
"requires": {
"signature_pad": "^2.3.2",
"trim-canvas": "^0.1.0"
}
},
"reactcss": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
"integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
"requires": {
"lodash": "^4.0.1"
}
},
"regenerator-runtime": {
"version": "0.13.7",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
@@ -1002,6 +1048,11 @@
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"signature_pad": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-2.3.2.tgz",
"integrity": "sha512-peYXLxOsIY6MES2TrRLDiNg2T++8gGbpP2yaC+6Ohtxr+a2dzoaqWosWDY9sWqTAAk6E/TyQO+LJw9zQwyu5kA=="
},
"string-convert": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
@@ -1017,6 +1068,11 @@
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
},
"trim-canvas": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/trim-canvas/-/trim-canvas-0.1.2.tgz",
"integrity": "sha1-YgRX9f7PVktSHTXF/NTaWDBNbkU="
},
"tslib": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",

View File

@@ -7,13 +7,14 @@
},
"author": "",
"license": "ISC",
"devDependencies": {},
"dependencies": {
"@antv/g2plot": "^1.1.27",
"antd": "^4.1.4",
"axios": "^0.20.0",
"codemirror": "^5.49.2",
"react": "^16.13.1",
"react-dom": "^16.13.1"
"react-color": "^2.19.3",
"react-dom": "^16.13.1",
"react-signature-canvas": "^1.0.3"
}
}