Skip to content

Commit

Permalink
Merge branch 'release-3.6.0' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
DominicWatson committed Nov 25, 2024
2 parents 5afeec2 + dfa220b commit 7515b7e
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v3.6.0

* Added a UI to show records in the DATA API change queue per subscribed API client

## v3.5.15

* Non string renderers: respect returned data when it is an empty array or struct for rendering in results
Expand Down
40 changes: 39 additions & 1 deletion handlers/admin/DataApiManager.cfc
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
component extends="preside.system.base.AdminHandler" {

property name="dataApiUserConfigurationService" inject="dataApiUserConfigurationService";
property name="messagebox" inject="messagebox@cbmessagebox";
property name="dataApiConfig" inject="coldbox:setting:rest.apis";
property name="messagebox" inject="messagebox@cbmessagebox";

function prehandler( event, rc, prc ) {
super.preHandler( argumentCollection = arguments );
Expand Down Expand Up @@ -186,6 +187,43 @@ component extends="preside.system.base.AdminHandler" {

}

public void function queueListing( event, rc, prc ) {
var restUserQueryFilter = "subscribe_to_deletes = :trueValue OR subscribe_to_updates = :trueValue OR subscribe_to_inserts = :trueValue";
var restUserQueryParams = { trueValue={ type="cf_sql_bit", value=true } };

if ( Len( Trim( rc.apiRoute ?: "" ) ) && StructKeyExists( dataApiConfig, rc.apiRoute ) ) {
prc.filterNamespace = dataApiConfig[ rc.apiRoute ].dataApiNamespace ?: "";

restUserQueryFilter = "( #restUserQueryFilter# ) AND namespace = :namespace";
restUserQueryParams.namespace = prc.filterNamespace;

event.addAdminBreadCrumb(
title = translateResource( uri="cms:apiManager.configureauth.page.breadcrumbTitle", data=[ rc.apiRoute ] )
, link = event.buildAdminLink( linkTo = "apimanager.configureAuth", queryString="id=#rc.apiRoute#" )
);
}

event.addAdminBreadCrumb(
title = translateResource( "cms:apiQueueListing.breadcrumbTitle" )
, link = event.buildAdminLink( linkTo="dataApiManager.queueListing" )
);

prc.pageIcon = "fa-stream";
prc.pageTitle = translateResource( "cms:apiQueueListing.page.title" );
prc.pageSubtitle = translateResource( "cms:apiQueueListing.page.subtitle" );

prc.activeRestUser = rc.restUser ?: "";
prc.queueRestUsers = getPresideObject( "data_api_user_settings" ).selectData(
groupBy = "user.name"
, filter = restUserQueryFilter
, filterParams = restUserQueryParams
, selectFields = [ "user.id", "user.name" ]
);

if ( isEmptyString( prc.activeRestUser ) ) {
prc.activeRestUser = prc.queueRestUsers.id ?: "";
}
}

private boolean function _checkPermissions( required any event, required string key, boolean throwOnError=true ) {
var hasPermission = hasCmsPermission( "apiManager." & arguments.key );
Expand Down
36 changes: 36 additions & 0 deletions handlers/admin/datamanager/data_api_queue.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
component {
property name="loginService" inject="LoginService";

private string function getAdditionalQueryStringForBuildAjaxListingLink( event, rc, prc, args={} ) {
var qs = [];
if ( Len( Trim( prc.activeRestUser ?: "" ) ) ) {
ArrayAppend( qs, "subscriber=#prc.activeRestUser#" );
}
if ( StructKeyExists( prc, "filterNamespace" ) ) {
ArrayAppend( qs, "namespace=#prc.filterNamespace#" );
}
return ArrayToList( qs, "&" );
}
private void function preFetchRecordsForGridListing( event, rc, prc, args={} ) {
args.extraFilters = args.extraFilters ?: [];

if ( Len( Trim( rc.subscriber ?: "" ) ) ) {
ArrayAppend( args.extraFilters, { filter={ subscriber=rc.subscriber } } );
}
if ( StructKeyExists( rc, "namespace" ) ) {
ArrayAppend( args.extraFilters, { filter={ namespace=rc.namespace } } );
}
}

private void function extraRecordActionsForGridListing( event, rc, prc, args={} ) {
args.actions = args.actions ?: [];

if ( Len( Trim( args.record.record_id ?: "" ) ) && Len( Trim( args.record.object_name ?: "" ) ) ) {
for ( var action in args.actions ) {
if ( ( action.contextKey ?: "" ) == "v" ) {
action.link = event.buildAdminLink( objectName=args.record.object_name, recordId=args.record.record_id );
}
}
}
}
}
8 changes: 8 additions & 0 deletions handlers/renderers/content/DataApiQueueObjectName.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
component {

private string function default( event, rc, prc, args={} ){
var objName = args.data ?: "";

return Len( Trim( objName ) ) ? "#translateResource( uri="preside-objects.#objName#:title", defaultValue=objName )# (#objName#)" : "";
}
}
7 changes: 7 additions & 0 deletions i18n/cms.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiQueueListing=Data API queue listing
apiQueueListing.breadcrumbTitle=API queue listing
apiQueueListing.iconclass=fa-stream
apiQueueListing.btn=Queue listing
apiQueueListing.page.title=Data API queue listing
apiQueueListing.page.subtitle=Manage API queue records
apiQueueListing.alert.no.queue.user.msg=There are no rest user subscribe to API queue in your application.
4 changes: 3 additions & 1 deletion i18n/preside-objects/data_api_queue.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ field.record_id.title=Record ID
field.operation.title=Operation
field.order_number.title=Order number
field.subscriber.title=Subscriber
field.data.title=Data
field.data.title=Data
field.is_checked_out.title=Checked out?
field.check_out_date.title=Check out date
6 changes: 5 additions & 1 deletion preside-objects/data_api_queue.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
* @nolabel true
* @noDateModified true
* @feature dataApiQueue
*
* @dataManagerEnabled true
* @datamanagerAllowedOperations read
* @datamanagerDefaultSortOrder order_number desc
*/
component {
property name="object_name" type="string" dbtype="varchar" maxlength=100 required=true indexes="object_name";
property name="object_name" type="string" dbtype="varchar" maxlength=100 required=true indexes="object_name" renderer="DataApiQueueObjectName";
property name="namespace" type="string" dbtype="varchar" maxlength=50 required=false indexes="namespace";
property name="queue_name" type="string" dbtype="varchar" maxlength=50 required=false indexes="queuename";
property name="record_id" type="string" dbtype="varchar" maxlength=100 required=true indexes="record_id";
Expand Down
13 changes: 13 additions & 0 deletions views/admin/apiManager/configureAuth.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!---@feature admin and apiManager--->
<cfoutput>
<cfif isFeatureEnabled( "dataApiQueue" )>
<div class="top-right-button-group">
<a class="pull-right btn btn-sm btn-info inline" href="#event.buildAdminLink( linkTo="dataApiManager.queueListing", querystring="apiRoute=#rc.id ?: ""#" )#">
<i class="fa fa-fw #translateResource( uri="cms:apiQueueListing.iconclass" )#"></i>
#translateResource( uri="cms:apiQueueListing.btn" )#
</a>
</div>
</cfif>

#( prc.body ?: "" )#
</cfoutput>
18 changes: 18 additions & 0 deletions views/admin/apiManager/index.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!---@feature admin and apiManager--->
<cfscript>
apis = prc.apis ?: [];
configLinkBase = prc.configLinkBase ?: "";
</cfscript>

<cfoutput>
<cfif isFeatureEnabled( "dataApiQueue" )>
<div class="top-right-button-group">
<a class="pull-right btn btn-sm btn-info inline" href="#event.buildAdminLink( linkTo="dataApiManager.queueListing" )#">
<i class="fa fa-fw #translateResource( uri="cms:apiQueueListing.iconclass" )#"></i>
#translateResource( uri="cms:apiQueueListing.btn" )#
</a>
</div>
</cfif>

<cfinclude template="/preside/system/views/admin/apiManager/index.cfm" />
</cfoutput>
43 changes: 43 additions & 0 deletions views/admin/dataApiManager/queueListing.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<cfscript>
queueRestUsers = prc.queueRestUsers ?: QueryNew( "" );
activeRestUser = Len( Trim( prc.activeRestUser ?: "" ) ) ? prc.activeRestUser : ( queueRestUsers.id ?: "" );
apiRoute = rc.apiRoute ?: "";
gridFields = prc.gridFields ?: [ "queue_name", "object_name", "record_id", "operation", "order_number" ];
if ( isEmptyString( apiRoute ) && !ArrayFindNoCase( gridFields, "namespace" ) ) {
ArrayPrepend( gridFields, "namespace" )
}
</cfscript>

<cfoutput>
<cfif !queueRestUsers.recordcount>
<p class="alert alert-warning">
<i class="fa fa-fw fa-exclamation-circle"></i>
#translateResource( "cms:apiQueueListing.alert.no.queue.user.msg" )#
</p>
<cfelse>
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
<cfloop query="#queueRestUsers#">
<li<cfif activeRestUser eq queueRestUsers.id> class="active"</cfif>>
<a href="#event.buildAdminLink(
linkto = "dataApiManager.queueListing"
, queryString = "restUser=#queueRestUsers.id##Len( Trim( apiRoute ) ) ? "&apiRoute=#apiRoute#" : ""#"
)#" >#queueRestUsers.name#</a>
</li>
</cfloop>
</ul>

<div class="tab-content">
<div id="tab-#activeRestUser#" class="tab-pane active">
#objectDataTable( objectName="data_api_queue", args={
gridFields = gridFields
, allowDataExport = false
, useMultiActions = false
, compact = true
} )#
</div>
</div>
</div>
</cfif>
</cfoutput>

0 comments on commit 7515b7e

Please sign in to comment.