Skip to content

Commit

Permalink
[DQT] add delete feature (#8078)
Browse files Browse the repository at this point in the history
Add delete feature for DQT
Add tools/dqt_delete_saved_query.php
  • Loading branch information
kongtiaowang committed Mar 17, 2023
1 parent 69c2610 commit ae89857
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -403,6 +403,7 @@ or not matching password confirmation. (PR #6615, #6705, #6611)

#### DQT
- Improve the visibility of some dropdown elements (PR #6602)
- ADD delete the saved query feature (PR #8078)

### Clean Up
- New tool for detection of multiple first visits for a candidate (prevents a database
Expand Down
37 changes: 37 additions & 0 deletions modules/dqt/ajax/DeleteDoc.php
@@ -0,0 +1,37 @@
<?php
/**
* Data Querying Module
*
* PHP Version 5
*
* @category Data_Querying_Module
* @package Loris
* @author Loris Team <loris-dev@bic.mni.mcgill.ca>
* @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3
* @link https://www.github.com/aces/Loris/
*/
header("Content-Type: application/json");
$config = \NDB_Config::singleton();
$couchConfig = $config->getSetting('CouchDB');
$cdb = \NDB_Factory::singleton()->couchDB(
$couchConfig['dbName'],
$couchConfig['hostname'],
intval($couchConfig['port']),
$couchConfig['admin'],
$couchConfig['adminpass']
);
$is_author = false;
$docID = urlencode($_REQUEST['DocID']);
$user = User::singleton();
$tmp_author = explode("_", $docID);
$doc_author = str_replace("global:", '', $tmp_author[0]);
if ($doc_author == $user->getUsername()) {
$is_author = true;
}

if ($user->hasPermission('superuser') || $is_author) {
$results = $cdb->deleteDoc($docID);
print json_encode($results);
} else {
header("HTTP/1.1 403 Forbidden");
}
2 changes: 1 addition & 1 deletion modules/dqt/ajax/saveQuery.php
Expand Up @@ -69,7 +69,7 @@
': ' .
$_REQUEST['QueryName'];
}
$fields = json_decode($_REQUEST['Fields']);
$fields = json_decode(strval($_REQUEST['Fields']));
$cond = $_REQUEST['Filters'];
$baseDocument['Conditions'] = $cond;
$baseDocument['Fields'] = $fields;
Expand Down
2 changes: 1 addition & 1 deletion modules/dqt/css/dataquery.css
Expand Up @@ -556,7 +556,7 @@ tr.statsReport:nth-child(even) {
}
.tableFieldsCell {
overflow-x: scroll;
max-width: 400px;
max-width: 280px;
min-height: 100px;
}
.tableFiltersCell {
Expand Down
2 changes: 2 additions & 0 deletions modules/dqt/jsx/react.app.js
Expand Up @@ -41,6 +41,7 @@ class DataQueryApp extends Component {
queryIDs: {
user: [],
shared: [],
author: [],
},
savedQueries: {},
queriesLoaded: false,
Expand Down Expand Up @@ -1346,6 +1347,7 @@ class DataQueryApp extends Component {
<SavedQueriesList
userQueries={this.state.queryIDs.user}
globalQueries={this.state.queryIDs.shared}
author={this.state.queryIDs.author}
queryDetails={this.state.savedQueries}
queriesLoaded={this.state.queriesLoaded}
onSelectQuery={this.loadSavedQuery}
Expand Down
59 changes: 56 additions & 3 deletions modules/dqt/jsx/react.savedqueries.js
Expand Up @@ -4,6 +4,7 @@
*/
import React, {useEffect, useState} from 'react';
import PropTypes from 'prop-types';
import swal from 'sweetalert2';

const ManageSavedQueryFilters = (props) => {
const [content, setContent] = useState(null);
Expand Down Expand Up @@ -70,7 +71,39 @@ const ManageSavedQueryFilters = (props) => {
const ManageSavedQueryRow = (props) => {
const [fieldsVisible, setFields] = useState(null);
const [filtersVisible, setFilters] = useState(null);

/**
* @deleteclick
*/
function publicquerydelete() {
const id = props.Query['_id'];
swal.fire({
title: 'Are you sure?',
text: 'You won\'t be able to revert this!',
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
}).then((result) => {
if (result.value) {
let deleteurl = loris.BaseURL +
'/AjaxHelper.php?Module=dqt&script=DeleteDoc.php&DocID='
+ encodeURIComponent(id);
fetch(deleteurl, {
cache: 'no-cache',
credentials: 'same-origin',
}).then((resp) => {
if (resp.status == 200) {
swal.fire('delete Successful!', '', 'success');
} else {
swal.fire('delete Not Successful!', '', 'error');
}
}).then(()=>{
location.reload();
});
}
});
};
useEffect(() => {
let fields = [];
let filters = [];
Expand Down Expand Up @@ -157,7 +190,21 @@ const ManageSavedQueryRow = (props) => {
setFilters(filters);
setFields(fields);
}, []);

let docName = props.Query.Meta['name'];
let docAuthor = docName.substring(0, docName.lastIndexOf(':'));
let btn = '';
if (props.author == docAuthor) {
btn = (
<button className='btn btn-danger'
onClick={()=> { // eslint-disable-line
publicquerydelete(); // eslint-disable-line
} // eslint-disable-line
} // eslint-disable-line
>
delete
</button>
);
}
return (
<tr>
<td>
Expand All @@ -175,6 +222,11 @@ const ManageSavedQueryRow = (props) => {
{filtersVisible}
</div>
</td>
<td>
<div className={'tableNameCell'}>
{btn}
</div>
</td>
</tr>
);
};
Expand All @@ -199,7 +251,6 @@ const SavedQueriesList = (props) => {
props.queryDetails[queryName].Conditions
);
};

if (props.queriesLoaded === false) {
return null;
}
Expand All @@ -222,6 +273,7 @@ const SavedQueriesList = (props) => {
<ManageSavedQueryRow key={name}
Name={queryName}
Query={query}
author={props.author}
/>
);
}
Expand All @@ -247,6 +299,7 @@ const SavedQueriesList = (props) => {
<th>Query Name</th>
<th>Fields</th>
<th>Filters</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
Expand Down
47 changes: 47 additions & 0 deletions modules/dqt/jsx/react.tabs.js
Expand Up @@ -11,6 +11,8 @@
import React, {Component, useState} from 'react';
import PropTypes from 'prop-types';
import StaticDataTable from '../../../jsx/StaticDataTable';
import swal from 'sweetalert2';

const {jStat} = require('jstat');
import JSZip from 'jszip';

Expand Down Expand Up @@ -1197,6 +1199,39 @@ class ManageSavedQueryRow extends Component {
super(props);
this.state = {};
}
/**
* @deleteclick
*/
deleteclick() {
let id = this.props.Query['_id'];
swal.fire({
title: 'Are you sure?',
text: 'You won\'t be able to revert this!',
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
}).then((result) => {
if (result.value) {
let deleteurl = loris.BaseURL +
'/AjaxHelper.php?Module=dqt&script=DeleteDoc.php&DocID='
+ encodeURIComponent(id);
fetch(deleteurl, {
cache: 'no-cache',
credentials: 'same-origin',
}).then((resp) => {
if (resp.status == 200) {
swal.fire('delete Successful!', '', 'success');
} else {
swal.fire('delete Not Successful!', '', 'error');
}
}).then(()=>{
location.reload();
});
}
});
}

/**
* Renders the React component.
Expand Down Expand Up @@ -1305,6 +1340,17 @@ class ManageSavedQueryRow extends Component {
{filters}
</div>
</td>
<td>
<div className={'tableNamesCell'}>
<button className='btn btn-danger'
onClick={()=> {
this.deleteclick();
}}
>
delete
</button>
</div>
</td>
</tr>
);
}
Expand Down Expand Up @@ -1377,6 +1423,7 @@ let ManageSavedQueriesTabPane = (props) => {
<th>Query Name</th>
<th>Fields</th>
<th>Filters</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
Expand Down
6 changes: 3 additions & 3 deletions modules/dqt/php/dqt_setup.class.inc
Expand Up @@ -164,12 +164,12 @@ class Dqt_Setup extends \NDB_Form implements RequestHandlerInterface
return $row['id'];
};

$usersavedNames = array_map($IDMapCallback, $usersaved);
$globalsavedNames = array_map($IDMapCallback, $globalsaved);

$usersavedNames = array_map($IDMapCallback, $usersaved);
$globalsavedNames = array_map($IDMapCallback, $globalsaved);
$data['savedqueries'] = [
'user' => $usersavedNames,
'shared' => $globalsavedNames,
'author' => $user->getUsername(),
];
$data['visits'] = \Utility::getVisitList();
// Note: StringStream since BinaryStream isn't in 23.0-release.
Expand Down
43 changes: 43 additions & 0 deletions tools/dqt_delete_saved_query.php
@@ -0,0 +1,43 @@
<?php
/**
* Data Querying Module
*
* PHP Version 7.4
*
* @category Data_Querying_Module
* @package Loris
* @author Loris Team <loris-dev@bic.mni.mcgill.ca>
* @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3
* @link https://www.github.com/aces/Loris/
*/
require_once __DIR__ . '/../vendor/autoload.php';
header("Content-Type: application/json");
$config = \NDB_Config::singleton();
$couchConfig = $config->getSetting('CouchDB');
$cdb = \NDB_Factory::singleton()->couchDB(
$couchConfig['dbName'],
$couchConfig['hostname'],
intval($couchConfig['port']),
$couchConfig['admin'],
$couchConfig['adminpass']
);
echo "Deleting a saved query in DQT.\n";

$user = readline("Please input the author of the saved query:");
$name = readline("Please input the name of the saved query:");
$global = readline("If the saved query is global then input 'y':");
if ($global) {
$docID = urlencode("global:".$user."_".$name);
} else {
$docID = urlencode($user."_".$name);
}
$results = $cdb->deleteDoc(
$docID
);


if (json_encode($results) == "true") {
echo $name." has been deleted in DQT.\n";
} else {
echo "There is no query named ".$name." in DQT.\n";
};

0 comments on commit ae89857

Please sign in to comment.