public inbox for [email protected]
help / color / mirror / Atom feedFrom: Aditya Toshniwal <[email protected]>
To: pgadmin-hackers <[email protected]>
Cc: Akshay Joshi <[email protected]>
Subject: Re: [pgAdmin][RM6130] React based framework for properties dialog and port Server Group, Server and Database dialogs
Date: Mon, 28 Jun 2021 15:57:10 +0530
Message-ID: <CAM9w-_k3ik+MBiYxbQTMMR=hWCqsHTvX7=LZLGVZkTF9t2U3+w@mail.gmail.com> (raw)
In-Reply-To: <CAM9w-_=UjoitLEooheh5yF3vvZHdoSv4hMpD0z3Ge9g0ri1cwQ@mail.gmail.com>
References: <CAM9w-_=RbH2Nt9cWRf5ZaE509-a2nxvDxdNYN=BakLGvM288Lg@mail.gmail.com>
<CA+OCxoxSOEBPErd-FXTHLi6gpVbo3TzkVQcZwzMg9P3+Cmnj6w@mail.gmail.com>
<CAM9w-_=FJqY-kJkEDzq7vXmBVv0SdbWe=Gkq2qBL9mbxYyA8pw@mail.gmail.com>
<CANxoLDexFZ4=EMO-r45RAJwopo-k54o6+QYr08H=KziEAm11dQ@mail.gmail.com>
<CAM9w-_=UjoitLEooheh5yF3vvZHdoSv4hMpD0z3Ge9g0ri1cwQ@mail.gmail.com>
Hi Hackers,
Please ignore the previous patch. Attached is the revised patch.
On Mon, Jun 28, 2021 at 2:50 PM Aditya Toshniwal <
[email protected]> wrote:
> Hi Hackers,
>
> I made some changes to the core code that will be helpful for other nodes.
> Please review.
>
>
> On Thu, Jun 24, 2021 at 5:39 PM Akshay Joshi <
> [email protected]> wrote:
>
>> Thanks, the patch applied in the "React_Porting" branch.
>>
>> On Mon, Jun 21, 2021 at 9:35 AM Aditya Toshniwal <
>> [email protected]> wrote:
>>
>>> Hi Dave,
>>>
>>> On Thu, Jun 17, 2021 at 7:26 PM Dave Page <[email protected]> wrote:
>>>
>>>> Hi
>>>>
>>>> On Thu, Jun 17, 2021 at 11:01 AM Aditya Toshniwal <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Hackers,
>>>>>
>>>>> Attached patch marks the beginning of migrating properties dialog/tab
>>>>> to React based code, which is easy to maintain, performant and testable
>>>>> using automation.
>>>>> Patch includes:
>>>>> - Framework for creating React based dynamic form view out of a
>>>>> pre-defined UI schema. Previously, it was based on Backform/Backbone.
>>>>> - The new framework and components will use MaterialUI as base.
>>>>> Previously, Bootstrap/Backform/jQuery components were used.
>>>>> - The new code uses JSS instead of CSS since material ui and most
>>>>> modern React libraries also use JSS. In future, this will allow us to
>>>>> change the theme in real-time without refresh.
>>>>> - 90% code covered by 80-85 new jasmine test cases.
>>>>> - Server group node UI Schema migration to new, with schema test cases.
>>>>> - Server node UI Schema migration to new, with schema test cases.
>>>>> - Database node UI Schema migration to new, with schema test cases.
>>>>> - Few other UI changes.
>>>>>
>>>>
>>>> Nice!
>>>>
>>>>
>>>>>
>>>>> PS: Until all the nodes are migrated, this will not go in the main
>>>>> branch.
>>>>>
>>>>
>>>> Yeah, how are we going to manage this? I agree with building it out in
>>>> a branch until we have full coverage of the dialogues, but I'm concerned
>>>> that it'll become a merge nightmare. Though, I guess we aren't touching the
>>>> dialogues much for other things right now, so maybe not.
>>>>
>>> We'll right now work only on the dialogs. So merging should be
>>> manageable.
>>> BTW, the patch can be merged in the main branch as well. It is backward
>>> compatible, and it will work fine. Only the UI components would look
>>> slightly different from the non-migrated dialogs.
>>>
>>>>
>>>> --
>>>> Dave Page
>>>> Blog: https://pgsnake.blogspot.com
>>>> Twitter: @pgsnake
>>>>
>>>> EDB: https://www.enterprisedb.com
>>>>
>>>>
>>>
>>> --
>>> Thanks,
>>> Aditya Toshniwal
>>> pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
>>> <http://edbpostgres.com;
>>> "Don't Complain about Heat, Plant a TREE"
>>>
>>
>>
>> --
>> *Thanks & Regards*
>> *Akshay Joshi*
>> *pgAdmin Hacker | Principal Software Architect*
>> *EDB Postgres <http://edbpostgres.com>*
>>
>> *Mobile: +91 976-788-8246*
>>
>
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>
--
Thanks,
Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"
Attachments:
[application/octet-stream] RM6130.part2revised.patch (11.6K, 3-RM6130.part2revised.patch)
download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
index fb42b37c5..769570961 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.ui.js
@@ -17,7 +17,7 @@ export class DefaultPrivSchema extends BaseUISchema {
this.getPrivilegeRoleSchema = getPrivilegeRoleSchema;
}
- get fields() {
+ get baseFields() {
return [
{
id: 'deftblacl', type: 'collection', group: gettext('Tables'),
@@ -89,7 +89,7 @@ export default class DatabaseSchema extends BaseUISchema {
return 'did';
}
- get fields() {
+ get baseFields() {
let obj = this;
return [
{
diff --git a/web/pgadmin/browser/static/js/node_view.jsx b/web/pgadmin/browser/static/js/node_view.jsx
index 837364769..9067b5a1b 100644
--- a/web/pgadmin/browser/static/js/node_view.jsx
+++ b/web/pgadmin/browser/static/js/node_view.jsx
@@ -171,12 +171,18 @@ export function getNodeView(nodeType, treeNodeInfo, actionType, itemNodeData, fo
inCatalog: inCatalog,
};
+ let schema = nodeObj.getSchema.call(nodeObj, treeNodeInfo, itemNodeData);
+ // Show/Hide security group for nodes under the catalog
+ if('catalog' in treeNodeInfo) {
+ schema.filterGroups = [gettext('Security')];
+ }
+
/* Fire at will, mount the DOM */
ReactDOM.render(
<SchemaView
formType={formType}
getInitData={initData}
- schema={nodeObj.getSchema.call(nodeObj, treeNodeInfo, itemNodeData)}
+ schema={schema}
viewHelperProps={viewHelperProps}
onSave={onSaveClick}
onClose={()=>containerPanel.close()}
diff --git a/web/pgadmin/static/js/SchemaView/DataGridView.jsx b/web/pgadmin/static/js/SchemaView/DataGridView.jsx
index 3cf16783b..89f9b519f 100644
--- a/web/pgadmin/static/js/SchemaView/DataGridView.jsx
+++ b/web/pgadmin/static/js/SchemaView/DataGridView.jsx
@@ -257,16 +257,16 @@ export default function DataGridView({
(viewHelperProps.serverInfo.version <= field.max_version))));
let _readonly = viewHelperProps.inCatalog || (viewHelperProps.mode == 'properties');
if(!_readonly) {
- _readonly = evalFunc(readonly, row.original || {});
+ _readonly = evalFunc(schema, readonly, row.original || {});
}
let _visible = true;
if(visible) {
- _visible = evalFunc(visible, row.original || {});
+ _visible = evalFunc(schema, visible, row.original || {});
}
_visible = _visible && verInLimit;
- disabled = evalFunc(disabled, row.original || {});
+ disabled = evalFunc(schema, disabled, row.original || {});
return <MappedCellControl rowIndex={row.index} value={value}
row={row.original} {..._field}
diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx
index 485d983dd..49d133d17 100644
--- a/web/pgadmin/static/js/SchemaView/FormView.jsx
+++ b/web/pgadmin/static/js/SchemaView/FormView.jsx
@@ -105,17 +105,17 @@ export default function FormView({
let _readonly = viewHelperProps.inCatalog || (viewHelperProps.mode == 'properties');
if(!_readonly) {
- _readonly = evalFunc(readonly, value);
+ _readonly = evalFunc(schema, readonly, value);
}
let _visible = true;
if(visible) {
- _visible = evalFunc(visible, value);
+ _visible = evalFunc(schema, visible, value);
}
_visible = _visible && verInLimit;
- disabled = evalFunc(disabled, value);
+ disabled = evalFunc(schema, disabled, value);
if(!tabs[group]) tabs[group] = [];
@@ -151,6 +151,7 @@ export default function FormView({
firstEleRef.current = ele;
}
}}
+ state={value}
key={field.id}
viewHelperProps={viewHelperProps}
name={field.id}
diff --git a/web/pgadmin/static/js/SchemaView/MappedControl.jsx b/web/pgadmin/static/js/SchemaView/MappedControl.jsx
index 46a815245..6195d610f 100644
--- a/web/pgadmin/static/js/SchemaView/MappedControl.jsx
+++ b/web/pgadmin/static/js/SchemaView/MappedControl.jsx
@@ -158,7 +158,7 @@ const ALLOWED_PROPS_FIELD_COMMON = [
];
const ALLOWED_PROPS_FIELD_FORM = [
- 'type', 'onChange'
+ 'type', 'onChange', 'state',
];
const ALLOWED_PROPS_FIELD_CELL = [
@@ -168,7 +168,7 @@ const ALLOWED_PROPS_FIELD_CELL = [
export const MappedFormControl = (props)=>{
let newProps = {...props};
- let typeProps = evalFunc(newProps.type, newProps.value);
+ let typeProps = evalFunc(null, newProps.type, newProps.state);
if(typeof(typeProps) === 'object') {
newProps = {
...newProps,
@@ -184,7 +184,7 @@ export const MappedFormControl = (props)=>{
export const MappedCellControl = (props)=>{
let newProps = {...props};
- let cellProps = evalFunc(newProps.cell, newProps.row);
+ let cellProps = evalFunc(null, newProps.cell, newProps.row);
if(typeof(cellProps) === 'object') {
newProps = {
...newProps,
diff --git a/web/pgadmin/static/js/SchemaView/base_schema.ui.js b/web/pgadmin/static/js/SchemaView/base_schema.ui.js
index fb01a24d2..7f9091dda 100644
--- a/web/pgadmin/static/js/SchemaView/base_schema.ui.js
+++ b/web/pgadmin/static/js/SchemaView/base_schema.ui.js
@@ -17,6 +17,7 @@ export default class BaseUISchema {
this._defaults = defaults;
this.keys = null; // If set, other fields except keys will be filtered
+ this.filterGroups = []; // If set, these groups will be filtered out
this.informText = null; // Inform text to show after save, this only saves it
this._top = null;
}
@@ -59,13 +60,26 @@ export default class BaseUISchema {
concat base fields with extraFields.
*/
get fields() {
- /* Select only keys if specified */
return this.baseFields
- .filter((field)=>this.keys ? this.keys.indexOf(field.id) > -1 : true);
+ .filter((field)=>{
+ let retval;
+
+ /* If any groups are to be filtered */
+ retval = this.filterGroups.indexOf(field.group) == -1;
+
+ /* Select only keys, if specified */
+ if(this.keys) {
+ retval = retval && this.keys.indexOf(field.id) > -1;
+ }
+ return retval;
+ });
}
/* Check if current data is new or existing */
isNew(state) {
+ if(_.isUndefined(state)) {
+ state = this.origData;
+ }
if(_.has(state, this.idAttribute)) {
return _.isUndefined(state[this.idAttribute])
|| _.isNull(state[this.idAttribute]);
diff --git a/web/pgadmin/static/js/SchemaView/index.jsx b/web/pgadmin/static/js/SchemaView/index.jsx
index c3106b36c..6fccc3daa 100644
--- a/web/pgadmin/static/js/SchemaView/index.jsx
+++ b/web/pgadmin/static/js/SchemaView/index.jsx
@@ -85,7 +85,10 @@ function getChangedData(topSchema, mode, sessData, stringify=false) {
return;
} else {
change = change || _.get(sessData, currPath);
- _.set(changedData, currPath, stringify ? JSON.stringify(change) : change);
+ if(stringify && (_.isArray(change) || _.isObject(change))) {
+ change = JSON.stringify(change);
+ }
+ _.set(changedData, currPath, change);
}
};
@@ -104,8 +107,8 @@ function getChangedData(topSchema, mode, sessData, stringify=false) {
/* Use diffArray package to get the array diff and extract the info
cid is used to identify the rows uniquely */
const changeDiff = diffArray(
- _.get(topSchema.origData, currPath),
- _.get(sessData, currPath),
+ _.get(topSchema.origData, currPath) || [],
+ _.get(sessData, currPath) || [],
'cid'
);
change = {};
@@ -437,7 +440,13 @@ function SchemaDialogView({
/* Called when SQL tab is active */
if(dirty) {
if(!formErr.name) {
- let changeData = getChangedData(schema, viewHelperProps.mode, sessData, true);
+ let changeData = {};
+ if(viewHelperProps.mode === 'edit') {
+ changeData = getChangedData(schema, viewHelperProps.mode, sessData, true);
+ } else {
+ /* If new then merge the changed data with origData */
+ changeData = _.merge(schema.origData, sessData);
+ }
/* Call the passed incoming getSQLValue func to get the SQL
return of getSQLValue should be a promise.
*/
@@ -566,10 +575,10 @@ function SchemaPropertiesView({
_visible = (field.mode.indexOf(viewHelperProps.mode) > -1);
}
if(_visible && visible) {
- _visible = evalFunc(visible, origData);
+ _visible = evalFunc(schema, visible, origData);
}
- disabled = evalFunc(disabled, origData);
+ disabled = evalFunc(schema, disabled, origData);
readonly = true;
if(_visible && verInLimit) {
if(!tabs[group]) tabs[group] = [];
diff --git a/web/pgadmin/static/js/Theme/index.jsx b/web/pgadmin/static/js/Theme/index.jsx
index 57bf72964..6a6e1fc29 100644
--- a/web/pgadmin/static/js/Theme/index.jsx
+++ b/web/pgadmin/static/js/Theme/index.jsx
@@ -251,17 +251,17 @@ function getFinalTheme(baseTheme) {
fontSize: baseTheme.typography.fontSize,
height: 'unset',
backgroundColor: baseTheme.palette.background.default,
- '&[readonly]': {
- backgroundColor: baseTheme.palette.inputDisabledBg,
- }
+ '&[readonly], &.Mui-disabled': {
+ backgroundColor: baseTheme.otherVars.inputDisabledBg,
+ },
},
input: {
fontSize: baseTheme.typography.fontSize,
height: 'unset',
backgroundColor: baseTheme.palette.background.default,
- '&[readonly]': {
+ '&[readonly], &.Mui-disabled': {
backgroundColor: baseTheme.otherVars.inputDisabledBg,
- }
+ },
}
},
MuiIconButton: {
diff --git a/web/pgadmin/static/js/components/FormComponents.jsx b/web/pgadmin/static/js/components/FormComponents.jsx
index 660366851..f495cf259 100644
--- a/web/pgadmin/static/js/components/FormComponents.jsx
+++ b/web/pgadmin/static/js/components/FormComponents.jsx
@@ -563,7 +563,9 @@ export function InputSelect({
}
}, [onChange]);
- const realValue = getRealValue(finalOptions, value, controlProps.creatable);
+ /* Apply filter if any */
+ const filteredOptions = (controlProps.filter && controlProps.filter(finalOptions)) || finalOptions;
+ const realValue = getRealValue(filteredOptions, value, controlProps.creatable);
const otherProps = {
isSearchable: !readonly,
isClearable: !readonly && (!_.isUndefined(controlProps.allowClear) ? controlProps.allowClear : true),
@@ -581,7 +583,7 @@ export function InputSelect({
openMenuOnClick: !readonly,
onChange: onChangeOption,
isLoading: isLoading,
- options: finalOptions,
+ options: filteredOptions,
value: realValue,
menuPortalTarget: document.body,
styles: styles,
diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js
index 81a3b0fe8..3eaa55283 100644
--- a/web/pgadmin/static/js/utils.js
+++ b/web/pgadmin/static/js/utils.js
@@ -410,9 +410,9 @@ function checkBinaryPathExists(binaryPathArray, selectedServerVersion) {
}
/* If a function, then evaluate */
-export function evalFunc(func, param) {
+export function evalFunc(obj, func, param) {
if(_.isFunction(func)) {
- return func.apply(null, [param]);
+ return func.apply(obj, [param]);
}
return func;
}
view thread (7+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected]
Subject: Re: [pgAdmin][RM6130] React based framework for properties dialog and port Server Group, Server and Database dialogs
In-Reply-To: <CAM9w-_k3ik+MBiYxbQTMMR=hWCqsHTvX7=LZLGVZkTF9t2U3+w@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox