Skip to content

Commit e48fd1f

Browse files
authored
COMPASS-2347: Databases and Collection in readonly mode (#1337)
1 parent 7fbc590 commit e48fd1f

File tree

5 files changed

+152
-93
lines changed

5 files changed

+152
-93
lines changed

src/internal-plugins/database-ddl/lib/component/databases-table.jsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class DatabasesTable extends React.Component {
7676
this.setState(state);
7777
}
7878

79+
isReadonlyDistro() {
80+
return process.env.HADRON_READONLY === 'true';
81+
}
82+
7983
renderNoCollections(isWritable) {
8084
return (
8185
<div className="no-collections-zero-state">
@@ -92,6 +96,19 @@ class DatabasesTable extends React.Component {
9296
);
9397
}
9498

99+
renderCreateDatabaseButton() {
100+
if (!this.isReadonlyDistro()) {
101+
return (
102+
<this.TextWriteButton
103+
className="btn btn-primary btn-xs"
104+
dataTestId="open-create-database-modal-button"
105+
text="Create Database"
106+
tooltipId="database-ddl-is-not-writable"
107+
clickHandler={this.onCreateDatabaseButtonClicked.bind(this)} />
108+
);
109+
}
110+
}
111+
95112
render() {
96113
if (this.props.databases === LOADING_STATE) {
97114
// Handled by the <Status> component
@@ -111,12 +128,7 @@ class DatabasesTable extends React.Component {
111128
return (
112129
<div className="rtss-databases" data-test-id="databases-table">
113130
<div className="rtss-databases-create-button action-bar controls-container">
114-
<this.TextWriteButton
115-
className="btn btn-primary btn-xs"
116-
dataTestId="open-create-database-modal-button"
117-
text="Create Database"
118-
tooltipId="database-ddl-is-not-writable"
119-
clickHandler={this.onCreateDatabaseButtonClicked.bind(this)} />
131+
{this.renderCreateDatabaseButton()}
120132
</div>
121133
<div className="column-container">
122134
<div className="column main">
@@ -128,7 +140,7 @@ class DatabasesTable extends React.Component {
128140
sortOrder={this.props.sortOrder}
129141
sortColumn={this.props.sortColumn}
130142
valueIndex={0}
131-
removable={this.state.isWritable}
143+
removable={this.state.isWritable && !this.isReadonlyDistro()}
132144
onColumnHeaderClicked={this.onColumnHeaderClicked.bind(this)}
133145
onRowDeleteButtonClicked={this.onRowDeleteButtonClicked.bind(this)}
134146
/>

src/internal-plugins/database/lib/components/collections-table.jsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,30 @@ class CollectionsTable extends React.Component {
5656
this.setState(state);
5757
}
5858

59+
isReadonlyDistro() {
60+
return process.env.HADRON_READONLY === 'true';
61+
}
62+
5963
renderLink(coll) {
6064
const collName = coll['Collection Name'];
6165
return (
6266
<a className="collections-table-link" href="#" onClick={this.onNameClicked.bind(this, collName)}>{collName}</a>
6367
);
6468
}
6569

70+
renderButton() {
71+
if (!this.isReadonlyDistro()) {
72+
return (
73+
<this.TextWriteButton
74+
className="btn btn-primary btn-xs"
75+
dataTestId="open-create-collection-modal-button"
76+
text="Create Collection"
77+
tooltipId="database-is-not-writable"
78+
clickHandler={this.onCreateCollectionButtonClicked.bind(this)} />
79+
);
80+
}
81+
}
82+
6683
render() {
6784
const rows = _.map(this.props.renderedCollections, (coll) => {
6885
const linkName = this.renderLink(coll);
@@ -84,12 +101,7 @@ class CollectionsTable extends React.Component {
84101
return (
85102
<div className="collections-table" data-test-id="collections-table">
86103
<div className="collections-table-create-button action-bar controls-container">
87-
<this.TextWriteButton
88-
className="btn btn-primary btn-xs"
89-
dataTestId="open-create-collection-modal-button"
90-
text="Create Collection"
91-
tooltipId="database-is-not-writable"
92-
clickHandler={this.onCreateCollectionButtonClicked.bind(this)} />
104+
{this.renderButton()}
93105
</div>
94106
<div className="column-container">
95107
<div className="column main">
@@ -101,7 +113,7 @@ class CollectionsTable extends React.Component {
101113
sortOrder={this.props.sortOrder}
102114
sortColumn={this.props.sortColumn}
103115
valueIndex={0}
104-
removable={this.state.isWritable}
116+
removable={this.state.isWritable && !this.isReadonlyDistro()}
105117
onColumnHeaderClicked={this.onColumnHeaderClicked.bind(this)}
106118
onRowDeleteButtonClicked={this.onRowDeleteButtonClicked.bind(this)}
107119
/>

src/internal-plugins/sidebar/lib/components/sidebar-collection.jsx

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class SidebarCollection extends React.Component {
5959
}
6060
}
6161

62+
isReadonlyDistro() {
63+
return process.env.HADRON_READONLY === 'true';
64+
}
65+
6266
renderReadonly() {
6367
if (this.props.readonly) {
6468
return (
@@ -67,25 +71,36 @@ class SidebarCollection extends React.Component {
6771
}
6872
}
6973

74+
renderDropCollectionButton() {
75+
if (!this.isReadonlyDistro()) {
76+
const tooltipText = this.state.isWritable ?
77+
'Drop collection' :
78+
this.state.description;
79+
const tooltipOptions = {
80+
'data-for': TOOLTIP_IDS.DROP_COLLECTION,
81+
'data-effect': 'solid',
82+
'data-offset': "{'bottom': 10, 'left': -5}",
83+
'data-tip': tooltipText
84+
};
85+
let dropClassName = 'compass-sidebar-icon compass-sidebar-icon-drop-collection fa fa-trash-o';
86+
if (!this.state.isWritable) {
87+
dropClassName += ' compass-sidebar-icon-is-disabled';
88+
}
89+
return (
90+
<i
91+
className={dropClassName}
92+
onClick={this.handleDropCollectionClick.bind(this, this.state.isWritable)}
93+
{...tooltipOptions} />
94+
);
95+
}
96+
}
97+
7098
render() {
7199
const collectionName = this.getCollectionName();
72-
const tooltipText = this.state.isWritable ?
73-
'Drop collection' :
74-
this.state.description;
75-
const tooltipOptions = {
76-
'data-for': TOOLTIP_IDS.DROP_COLLECTION,
77-
'data-effect': 'solid',
78-
'data-offset': "{'bottom': 10, 'left': -5}",
79-
'data-tip': tooltipText
80-
};
81100
let itemClassName = 'compass-sidebar-item compass-sidebar-item-is-actionable';
82101
if (this.props.activeNamespace === this.props._id) {
83102
itemClassName += ' compass-sidebar-item-is-active';
84103
}
85-
let dropClassName = 'compass-sidebar-icon compass-sidebar-icon-drop-collection fa fa-trash-o';
86-
if (!this.state.isWritable) {
87-
dropClassName += ' compass-sidebar-icon-is-disabled';
88-
}
89104
return (
90105
<div className={itemClassName}>
91106
<div
@@ -97,11 +112,7 @@ class SidebarCollection extends React.Component {
97112
{this.renderReadonly()}
98113
</div>
99114
<div className="compass-sidebar-item-actions compass-sidebar-item-actions-ddl">
100-
<i
101-
className={dropClassName}
102-
onClick={this.handleDropCollectionClick.bind(this, this.state.isWritable)}
103-
{...tooltipOptions}
104-
/>
115+
{this.renderDropCollectionButton()}
105116
</div>
106117
</div>
107118
);

src/internal-plugins/sidebar/lib/components/sidebar-database.jsx

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,37 +87,63 @@ class SidebarDatabase extends React.Component {
8787
}
8888
}
8989

90+
isReadonlyDistro() {
91+
return process.env.HADRON_READONLY === 'true';
92+
}
93+
94+
renderCreateCollectionButton() {
95+
if (!this.isReadonlyDistro()) {
96+
const createTooltipText = this.state.isWritable ?
97+
'Create collection' :
98+
this.state.description;
99+
const createTooltipOptions = {
100+
'data-for': TOOLTIP_IDS.CREATE_COLLECTION,
101+
'data-effect': 'solid',
102+
'data-offset': "{'bottom': 10, 'left': -8}",
103+
'data-tip': createTooltipText
104+
};
105+
let createClassName = 'mms-icon-add-circle compass-sidebar-icon compass-sidebar-icon-create-collection';
106+
if (!this.state.isWritable) {
107+
createClassName += ' compass-sidebar-icon-is-disabled';
108+
}
109+
return (
110+
<i
111+
className={createClassName}
112+
onClick={this.handleCreateCollectionClick.bind(this, this.state.isWritable)}
113+
{...createTooltipOptions} />
114+
);
115+
}
116+
}
117+
118+
renderDropDatabaseButton() {
119+
if (!this.isReadonlyDistro()) {
120+
const dropTooltipText = this.state.isWritable ?
121+
'Drop database' :
122+
'Drop database is not available on a secondary node'; // TODO: Arbiter/recovering/etc
123+
const dropTooltipOptions = {
124+
'data-for': TOOLTIP_IDS.DROP_DATABASE,
125+
'data-effect': 'solid',
126+
'data-offset': "{'bottom': 10, 'left': -5}",
127+
'data-tip': dropTooltipText
128+
};
129+
let dropClassName = 'compass-sidebar-icon compass-sidebar-icon-drop-database fa fa-trash-o';
130+
if (!this.state.isWritable) {
131+
dropClassName += ' compass-sidebar-icon-is-disabled';
132+
}
133+
return (
134+
<i
135+
className={dropClassName}
136+
onClick={this.handleDropDBClick.bind(this, this.state.isWritable)}
137+
{...dropTooltipOptions} />
138+
);
139+
}
140+
}
141+
90142
render() {
91-
const createTooltipText = this.state.isWritable ?
92-
'Create collection' :
93-
this.state.description;
94-
const createTooltipOptions = {
95-
'data-for': TOOLTIP_IDS.CREATE_COLLECTION,
96-
'data-effect': 'solid',
97-
'data-offset': "{'bottom': 10, 'left': -8}",
98-
'data-tip': createTooltipText
99-
};
100-
const dropTooltipText = this.state.isWritable ?
101-
'Drop database' :
102-
'Drop database is not available on a secondary node'; // TODO: Arbiter/recovering/etc
103-
const dropTooltipOptions = {
104-
'data-for': TOOLTIP_IDS.DROP_DATABASE,
105-
'data-effect': 'solid',
106-
'data-offset': "{'bottom': 10, 'left': -5}",
107-
'data-tip': dropTooltipText
108-
};
109143
let headerClassName = 'compass-sidebar-item-header compass-sidebar-item-header-is-expandable compass-sidebar-item-header-is-actionable';
110144
if (this.props.activeNamespace === this.props._id) {
111145
headerClassName += ' compass-sidebar-item-header-is-active';
112146
}
113-
let createClassName = 'mms-icon-add-circle compass-sidebar-icon compass-sidebar-icon-create-collection';
114-
if (!this.state.isWritable) {
115-
createClassName += ' compass-sidebar-icon-is-disabled';
116-
}
117-
let dropClassName = 'compass-sidebar-icon compass-sidebar-icon-drop-database fa fa-trash-o';
118-
if (!this.state.isWritable) {
119-
dropClassName += ' compass-sidebar-icon-is-disabled';
120-
}
121147
return (
122148
<div className="compass-sidebar-item compass-sidebar-item-is-top-level" style={this.props.style}>
123149
<div className={headerClassName}>
@@ -131,16 +157,8 @@ class SidebarDatabase extends React.Component {
131157
{this.props._id}
132158
</div>
133159
<div className="compass-sidebar-item-header-actions compass-sidebar-item-header-actions-ddl">
134-
<i
135-
className={createClassName}
136-
onClick={this.handleCreateCollectionClick.bind(this, this.state.isWritable)}
137-
{...createTooltipOptions}
138-
/>
139-
<i
140-
className={dropClassName}
141-
onClick={this.handleDropDBClick.bind(this, this.state.isWritable)}
142-
{...dropTooltipOptions}
143-
/>
160+
{this.renderCreateCollectionButton()}
161+
{this.renderDropDatabaseButton()}
144162
</div>
145163
</div>
146164
<div className="compass-sidebar-item-content">

src/internal-plugins/sidebar/lib/components/sidebar.jsx

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ class Sidebar extends React.Component {
148148
return null;
149149
}
150150

151+
isReadonlyDistro() {
152+
return process.env.HADRON_READONLY === 'true';
153+
}
154+
151155
/**
152156
* On expand/collapse of sidebar-database, add/remove from expandedDBs state and recompute row heights
153157
* @param{string} _id sidebar-database _id
@@ -160,32 +164,34 @@ class Sidebar extends React.Component {
160164
}
161165

162166
renderCreateDatabaseButton() {
163-
const tooltipText = this.state.description;
164-
const tooltipOptions = this.state.isWritable ? {} : {
165-
'data-for': TOOLTIP_IDS.CREATE_DATABASE_BUTTON,
166-
'data-effect': 'solid',
167-
'data-place': 'right',
168-
'data-offset': "{'right': -10}",
169-
'data-tip': tooltipText
170-
};
171-
let className = 'compass-sidebar-button-create-database';
172-
if (!this.state.isWritable) {
173-
className += ' compass-sidebar-button-is-disabled';
167+
if (!this.isReadonlyDistro()) {
168+
const tooltipText = this.state.description;
169+
const tooltipOptions = this.state.isWritable ? {} : {
170+
'data-for': TOOLTIP_IDS.CREATE_DATABASE_BUTTON,
171+
'data-effect': 'solid',
172+
'data-place': 'right',
173+
'data-offset': "{'right': -10}",
174+
'data-tip': tooltipText
175+
};
176+
let className = 'compass-sidebar-button-create-database';
177+
if (!this.state.isWritable) {
178+
className += ' compass-sidebar-button-is-disabled';
179+
}
180+
return (
181+
<div className="compass-sidebar-button-create-database-container" {...tooltipOptions}>
182+
<button
183+
className={className}
184+
title="Create Database"
185+
onClick={this.handleCreateDatabaseClick.bind(this, this.state.isWritable)}
186+
>
187+
<i className="mms-icon-add" />
188+
<text className="plus-button">
189+
Create Database
190+
</text>
191+
</button>
192+
</div>
193+
);
174194
}
175-
return (
176-
<div className="compass-sidebar-button-create-database-container" {...tooltipOptions}>
177-
<button
178-
className={className}
179-
title="Create Database"
180-
onClick={this.handleCreateDatabaseClick.bind(this, this.state.isWritable)}
181-
>
182-
<i className="mms-icon-add" />
183-
<text className="plus-button">
184-
Create Database
185-
</text>
186-
</button>
187-
</div>
188-
);
189195
}
190196

191197
renderSidebarDatabase({index, key, style}) {

0 commit comments

Comments
 (0)