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
+36 -2
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 [
+1 -1
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');
+2 -2
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) {
+18
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;
+166
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 };
+9 -6
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: {
+3
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: '' }],
];
+1 -22
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() {
+1 -1
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' }],
];
}
+50 -3
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' }],
-2
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;
+5 -5
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';
+1 -1
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']],
+208 -207
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;
+134
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;
+71
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;
+49 -14
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;
}
}
+45
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;
+58
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;
+30 -1
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;
+70
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;
+2
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 &&
+59 -14
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;
}
+1
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) {
+83
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;
+1
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) {
-3
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 {
+1 -1
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');
}
+70
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;
}
+22 -1
View File
File diff suppressed because one or more lines are too long
+1 -7
View File
File diff suppressed because one or more lines are too long
+23 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+49 -49
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) {
+49 -49
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) {
+1 -1
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
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",
+3 -2
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"
}
}