Skip to content

Showing * for required Columns #1720

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 23, 2021
12 changes: 9 additions & 3 deletions src/components/BrowserCell/BrowserCell.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,13 @@ export default class BrowserCell extends Component {
//#endregion

render() {
let { type, value, hidden, width, current, onSelect, onEditChange, setCopyableValue, setRelation, onPointerClick, row, col, field, onEditSelectedRow, readonly } = this.props;
let { type, value, hidden, width, current, onSelect, onEditChange, setCopyableValue, setRelation, onPointerClick, row, col, field, onEditSelectedRow, readonly, isRequired, markRequiredField } = this.props;
let content = value;
let isNewRow = row < 0;
this.copyableValue = content;
let classes = [styles.cell, unselectable];
if (hidden) {
content = '(hidden)';
content = value !== undefined || !isNewRow ? '(hidden)' : isRequired ? '(required)' : '(undefined)';
classes.push(styles.empty);
} else if (value === undefined) {
if (type === 'ACL') {
Expand All @@ -228,6 +229,7 @@ export default class BrowserCell extends Component {
this.copyableValue = content = '(undefined)';
classes.push(styles.empty);
}
content = isNewRow && isRequired && value === undefined ? '(required)' : content;
} else if (value === null) {
this.copyableValue = content = '(null)';
classes.push(styles.empty);
Expand Down Expand Up @@ -303,6 +305,10 @@ export default class BrowserCell extends Component {
classes.push(styles.current);
}

if (markRequiredField && isRequired && !value) {
classes.push(styles.required);
}

return readonly ? (
<Tooltip placement='bottom' tooltip='Read only (CTRL+C to copy)' visible={this.state.showTooltip} >
<span
Expand All @@ -324,7 +330,7 @@ export default class BrowserCell extends Component {
}
}}
>
{row < 0 ? '(auto)' : content}
{isNewRow ? '(auto)' : content}
</span>
</Tooltip>
) : (
Expand Down
15 changes: 15 additions & 0 deletions src/components/BrowserCell/BrowserCell.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,18 @@
bottom: 0;
}
}

.required {
position: relative;

&:after {
position: absolute;
pointer-events: none;
content: '';
border: 2px solid #ff395e;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
5 changes: 4 additions & 1 deletion src/components/BrowserRow/BrowserRow.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class BrowserRow extends Component {
}

render() {
const { className, columns, currentCol, isUnique, obj, onPointerClick, order, readOnlyFields, row, rowWidth, selection, selectRow, setCopyableValue, setCurrent, setEditing, setRelation, onEditSelectedRow, setContextMenu, onFilterChange } = this.props;
const { className, columns, currentCol, isUnique, obj, onPointerClick, order, readOnlyFields, row, rowWidth, selection, selectRow, setCopyableValue, setCurrent, setEditing, setRelation, onEditSelectedRow, setContextMenu, onFilterChange, markRequiredField, requiredColumnFields } = this.props;
let attributes = obj.attributes;
return (
<div className={styles.tableRow} style={{ minWidth: rowWidth }}>
Expand Down Expand Up @@ -58,6 +58,7 @@ export default class BrowserRow extends Component {
hidden = true;
}
}
let isRequired = requiredColumnFields && requiredColumnFields.includes(name);
return (
<BrowserCell
key={name}
Expand All @@ -80,6 +81,8 @@ export default class BrowserRow extends Component {
objectId={obj.id}
value={attr}
hidden={hidden}
isRequired={isRequired}
markRequiredField={markRequiredField}
setCopyableValue={setCopyableValue}
setContextMenu={setContextMenu}
onEditSelectedRow={onEditSelectedRow} />
Expand Down
109 changes: 107 additions & 2 deletions src/dashboard/Data/Browser/Browser.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class Browser extends DashboardView {

isUnique: false,
uniqueField: null,
markRequiredField: false,
requiredColumnFields: []
};

this.prefetchData = this.prefetchData.bind(this);
Expand Down Expand Up @@ -123,6 +125,7 @@ class Browser extends DashboardView {
this.onDialogToggle = this.onDialogToggle.bind(this);
this.abortAddRow = this.abortAddRow.bind(this);
this.saveNewRow = this.saveNewRow.bind(this);
this.setRequiredColumnFields = this.setRequiredColumnFields.bind(this);
}

componentWillMount() {
Expand Down Expand Up @@ -280,14 +283,26 @@ class Browser extends DashboardView {
required,
defaultValue
};
this.props.schema.dispatch(ActionTypes.ADD_COLUMN, payload).catch((err) => {
this.props.schema.dispatch(ActionTypes.ADD_COLUMN, payload).then(() => {
// if new required field column is added, then add field in requiredColumn
if (required) {
let requiredCols = [...this.state.requiredColumnFields, name];
this.setState({
requiredColumnFields: requiredCols
});
}
}).catch((err) => {
this.showNote(err.message, true);
}).finally(() => {
this.setState({ showAddColumnDialog: false });
});
}

addRow() {
if (this.props.params.className === '_User') {
// if User class row, then reload requiredFields
this.setRequiredColumnFields();
}
if (!this.state.newObject) {
const relation = this.state.relation;
this.setState({
Expand All @@ -304,6 +319,11 @@ class Browser extends DashboardView {
newObject: null
});
}
if (this.state.markRequiredField) {
this.setState({
markRequiredField: false
});
}
}

saveNewRow(){
Expand All @@ -312,6 +332,45 @@ class Browser extends DashboardView {
return;
}

// check if required fields are missing
const className = this.props.params.className;
let requiredCols = [];
if (className) {
let classColumns = this.props.schema.data.get('classes').get(className);
classColumns.forEach(({ required }, name) => {
if (name === 'objectId' || this.state.isUnique && name !== this.state.uniqueField) {
return;
}
if (!!required) {
requiredCols.push(name);
}
if (className === '_User' && (name === 'username' || name === 'password')) {
if (!obj.get('authData')) {
requiredCols.push(name);
}
}
if (className === '_Role' && (name === 'name' || name === 'ACL')) {
requiredCols.push(name);
}
});
}
if (requiredCols.length) {
for (let idx = 0; idx < requiredCols.length; idx++) {
const name = requiredCols[idx];
if (!obj.get(name)) {
this.showNote("Please enter all required fields", true);
this.setState({
markRequiredField: true
});
return;
}
}
}
if (this.state.markRequiredField) {
this.setState({
markRequiredField: false
});
}
obj.save(null, { useMasterKey: true }).then(
objectSaved => {
let msg = objectSaved.className + ' with id \'' + objectSaved.id + '\' created';
Expand Down Expand Up @@ -483,6 +542,30 @@ class Browser extends DashboardView {
delete filteredCounts[source];
}
this.setState({ data: data, filters, lastMax: MAX_ROWS_FETCHED , filteredCounts: filteredCounts});
this.setRequiredColumnFields();
}

setRequiredColumnFields() {
if (!this.props.schema.data.get('classes')) {
return;
}
let classes = this.props.schema.data.get('classes');
const { className } = this.props.params;
let requiredCols = [];
classes.get(className).forEach(({ required }, name) => {
if (!!required) {
requiredCols.push(name);
}
if (className === '_User' && (name === 'username' || name === 'password' || name === 'authData')) {
requiredCols.push(name);
}
if (className === '_Role' && (name === 'name' || name === 'ACL')) {
requiredCols.push(name);
}
});
this.setState({
requiredColumnFields: requiredCols
});
}

async fetchRelation(relation, filters = new List()) {
Expand Down Expand Up @@ -636,7 +719,27 @@ class Browser extends DashboardView {
} else {
obj.set(attr, value);
}
if(isNewObject){

if (isNewObject) {
// for dynamically changing required placeholder text for _User class new row object
if (obj.className === '_User' && attr === 'authData' && value !== undefined) {
// username & password are not required
this.setState({
requiredColumnFields: this.state.requiredColumnFields.filter(field => field !== 'username' && field !== 'password')
})
}

if (obj.className === '_User' && (attr === 'username' || attr === 'password') && value !== undefined) {
// authData is not required
this.setState({
requiredColumnFields: this.state.requiredColumnFields.filter(field => field !== 'authData')
})
}

if (obj.className === '_User' && obj.get('username') === undefined && obj.get('password') === undefined && obj.get('authData') === undefined) {
this.setRequiredColumnFields();
}

this.setState({
isNewObject: obj
});
Expand Down Expand Up @@ -1076,6 +1179,8 @@ class Browser extends DashboardView {
onSaveNewRow={this.saveNewRow}
onAbortAddRow={this.abortAddRow}

markRequiredField={this.state.markRequiredField}
requiredColumnFields={this.state.requiredColumnFields}
columns={columns}
className={className}
fetchNextPage={this.fetchNextPage}
Expand Down
7 changes: 5 additions & 2 deletions src/dashboard/Data/Browser/BrowserTable.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,16 @@ export default class BrowserTable extends React.Component {
}
}

let headers = this.props.order.map(({ name, width, visible, preventSort }) => (
let headers = this.props.order.map(({ name, width, visible, preventSort, required }) => (
{
width: width,
name: name,
type: this.props.columns[name].type,
targetClass: this.props.columns[name].targetClass,
order: ordering.col === name ? ordering.direction : null,
visible,
preventSort
preventSort,
required
}
));
let editor = null;
Expand Down Expand Up @@ -142,6 +143,8 @@ export default class BrowserTable extends React.Component {
setCopyableValue={this.props.setCopyableValue}
setContextMenu={this.props.setContextMenu}
onEditSelectedRow={this.props.onEditSelectedRow}
markRequiredField={this.props.markRequiredField}
requiredColumnFields={this.props.requiredColumnFields}
/>
<Button
value="Add"
Expand Down
8 changes: 6 additions & 2 deletions src/lib/ColumnPreferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,25 @@ export function getOrder(cols, appId, className, defaultPrefs) {
for (let name in cols) {
requested[name] = true;
if (!seen[name]) {
order.push({ name: name, width: DEFAULT_WIDTH, visible: !defaultPrefs });
order.push({ name: name, width: DEFAULT_WIDTH, visible: !defaultPrefs, required: cols[name]['required'] });
seen[name] = true;
updated = true;
}
}
let filtered = [];
for (let i = 0; i < order.length; i++) {
const { name, visible } = order[i];
const { name, visible, required } = order[i];

// If "visible" attribute is not defined, sets to true
// and updates the cached preferences.
if (typeof visible === 'undefined') {
order[i].visible = true;
updated = true;
}
// If "required" attribute is not defined, set it to false
if (typeof required === 'undefined') {
order[i].required = false;
}
if (requested[name]) {
filtered.push(order[i]);
} else {
Expand Down