PSPDFKIT adding stamps to each page - pspdfkit

Checking through the trial for using this framework for my client and while I can add a "received" stamp on a single page there doesn't seem to be a way to add a stamp to each page automatically. Does the framework support that without calling the API for each page? Is this better done in the front-end UI?

Yes, you need to add the stamp to each page, but it can be done in a single call to instance.create() by passing an array of stamp annotations:
instance.create(
Array.from({
length: instance.totalPageCount
}).map((_, pageIndex) =>
new PSPDFKit.Annotations.StampAnnotation({
pageIndex,
// other annotation properties
})
)
)
However, "received" is not a built-in stamp annotation type, so you'll probably have to use image annotations instead.

Related

Vaadin 23. Unable to access '$server' handle to call a #ClientCallable backend method

I have a TypeScript component which extends LitElement. I want to fetch some data from db from time to time and render the data on this component. I assume the component logic to be responsible for collecting that data since there are going to be a few similar ones. So I am trying to call the component's server method, marked by #ClientCallable annotation and return the JsonValue data. For this I am using the $server handle which is meaned to be a field a component, according to the docs https://vaadin.com/docs/latest/create-ui/element-api/client-server-rpc . But there is no $server defined. How do I make it work?
Here is my repro https://github.com/asdnf/vaadin-sample.git

In a list, set the default sort column in jhipster

sorry for simple question, but I'm new both to spring, JPA and Jhipster.
I'm following a video tutorial, and in one step the teacher was "customizing" the default view to sort on a custom column. He did so by changing the method in the repository class, to a query that ordered by one of the columns. This works, but I noticed that doing that the UI sort (the sort the UI impose clicking on the column) stopped working.
Debugging i noticed that the reason is that the query filter first by date, then by "pageable".
What is the best practice to apply the "byDate" sort just as a default, in case the pageable is empty?
I managed to "hack" the system by deep inspecting the page object and with an "if there is an UI sort use repository method A (the one that is natively unsorted), if there is not use repository method B (the one that is already sorted)". What I'm looking for is the "right way", the best practice, because I want to learn to program the way it is supposed to be, and I'm pretty sure that to have a default sort column is not a such exotic request
Here it is the link to the video
many thanks
You can set the default sorting column of any view in the [component-name].route.ts. In that file you will see something like this:
// ...
export const fooRoute: Routes = [
{
path: '',
component: FooComponent,
resolve: {
pagingParams: JhiResolvePagingParams
},
data: {
authorities: ['ROLE_USER'],
defaultSort: 'id,asc', // <- Look at this line :)
pageTitle: 'jhipsterApp.foo.home.title'
},
canActivate: [UserRouteAccessService]
},
// ...
The default order set by JHipster is by column id in ascending order. If you want to set the default order by column name descending (just as an example) just change that line to the following:
defaultSort: 'name,desc',
My app is generated via recent JHipster 7.4.1 and uses Vue frontned.
There are no [component-name].route.ts files generated.
I tried to add defaultSort into entities.ts but no luck.
This is working here:
In the [entity-name].components.ts,
change
public propOrder = 'id';
into
public propOrder = '[your default sort column, e.g. name]';

How to use actions.intent.DATETIME?

It is "clearly" defined in the documentation, but I can find no example of how to use actions.intent.DATETIME.
Please provide an example of what is needed in the 'action.json' file, and how my code can get the date and time provided using the assistant SDK helper. I haven't been able to figure out how to use actions.intent.___ at all!
At the simplest level, I want my code to know whether it is morning or evening for the person since I need to give different information in each case. Someone might want to do this to respond "Good morning" or "Good evening".
Also to do with intents, at a more complex level, I also want to know their approximate location (lat/long). I figured that once I know how to work with DATETIME, I'd be able to apply the same code pattern to use getDeviceLocation.
There is some code at https://github.com/actions-on-google/actions-on-google-nodejs that uses the DATETIME intent, but it asks the user for any time. I want to simply know what their current time is.
The DateTime intent can be invoked using the askForDateTime() method from the ActionsSdkApp class in our client library. Simply call the method from an intent, and pass it some queries which clarify the prompting. Then listen for the response using a listener for the actions.intent.DATETIME intent, just as you would listen for the actions.intent.TEXT intent.
In the handler for the actions.intent.DATETIME intent, you can use the getDateTime() method to retrieve the data. Unfortunately this intent only works by asking for an exact date and time from the user, and it is a generic date and time, so there is no guarantee that it is their current datetime unless you structure your prompts in a way to guide the user towards that.
const app = new ActionsSdkApp({ request, response });
function welcomeIntent (app) {
app.askForDateTime('When do you want to come in?',
Which date works best for you?',
'What time of day works best for you?');
}
function datetime (app) {
app.tell({speech: 'Great see you at your appointment!',
displayText: 'Great, we will see you on '
+ app.getDateTime().date.month
+ '/' + app.getDateTime().date.day
+ ' at ' + app.getDateTime().time.hours
+ (app.getDateTime().time.minutes || '')});
}
const actionMap = new Map();
actionMap.set(app.StandardIntents.MAIN, welcomeIntent);
actionMap.set(app.StandardIntents.DATETIME, datetime);
app.handleRequest(actionMap);
As you mentioned you can invoke and handle the actions.intent.PERMISSION intent in a similar way to get a precise longitude and latitude location.
As a side note, if you are using API.AI, you can use their Date and Time system entities to do this, or use the askForDateTime() method in the ApiAiApp class from the client library.
You can em-bed the maps API location/time in your app JSON or, other open source. As far as location it is device and user settings specific so, whether or not you get a JSNODE response from the device/user depends on the user even if they are running the APP and, have different setting preferences.

load only components scripts that are in the current page

What I'm trying to achieve is that if i have 2 components nodes :
component1
clientlib
component1.js
component2
clientlib
component2.js
and i drag them into page1, then when page1 is generated, only component1.js and component2.js will be loaded when navigating to page1 .
One approach i saw is to use custom Tag Library as described here : http://www.icidigital.com/blog/best-approaches-clientlibs-aem-part-3/
I have two questions :
1) is there an existing feature in AEM to do this ?
2) if not, what is the easiest way to create such custom Tag Library ?
EDIT:
Assume that there is no ability to just include all component clientLibs, rather load only those that are added to the page.
There is no built in feature to do this. Although I've heard that the clientlib infrastructure is being looked at for a re-write so I'm optimistic that something like this will be added in the future.
We have, and I know other company have, created a "deferred script tag." Ours is a very simple tag that take a chunk of html like a clientlib include, add it to a unique list and then on an out call at the footer, spits it all out one after another.
Here's the core of a simple tag implementation that extends BodyTagSupport. Then in your footer grab the attribute and write it out.
public int doEndTag() throws JspException {
SlingHttpServletRequest request = (SlingHttpServletRequest)pageContext.getAttribute("slingRequest");
Set<String> delayed = (Set<String>)request.getAttribute(DELAYED_INCLUDE);
if(delayed == null){
delayed = new HashSet<String>();
}
if(StringUtils.isNotBlank(this.bodyContent.getString())){
delayed.add(this.bodyContent.getString().trim());
}
request.setAttribute(DELAYED_INCLUDE, delayed);
return EVAL_PAGE;
}
Theoretically the possible way of doing is to write script in your page component/abstract page component that does something like this -
Step1 : String path = currentPage.getPath()
Step2 : Query this path for components (one way is to have a master list do a contains clause on sling:resourceType)
Step 3: User resource resolver to resolve the resourceType in Step 3, this will give you resource under your apps.
Step 4: From the above resource get the sub-resource with primary type as cq:ClientLibraryFolder
Step 5: from the client libs resource in Step 4 get the categories and include the JS from them
you could actually write a model to adapt a component resource to a clientLibrary to actually clean the code.
Let me know if you need actual code, I can write that in my free time.

Extbase Hooks - execute code upon record creation

I want to create a standard typo3 extension but when I create a record (or modify it) I want to calculate something (in my case I want to call the Google Map API to get coordinates from a given address).
SO I search for a hook or something. Any idea?
One of my project example, may helps you for hook in backend when record has been changed.
In your extension file ext_localconf.php
// Hook for cancellation
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = 'EXT:femanager/class.tx_femanager_tcemainprocdm.php:tx_femanager_tcemainprocdm';
hook file class.tx_femanager_tcemainprocdm.php where you can execute
your script
class tx_femanager_tcemainprocdm{
function processDatamap_postProcessFieldArray ($status, $table, $id, &$fieldArray, &$reference){
// $status also called action like delete
// $table - table name of excute backend action
// $id - record UID
// $fieldArray - fields of your table
if($table = 'your_extension_table_name'){
// your script
}
}
}
Maybe this answer is useful to you.
Register your class as a data handling hook in your extension. This one "is called AFTER all commands of the commandmap" were executed. Maybe you need to look for a more appropriate one.
Then in your registered Hook i.e. 'typo3conf/ext/your_ext/Classes/Hooks/AfterCreate.php' do your calculation. Hope this sets you on the right track.
In my special case there was no need to calculate the coordinates when the record got saved. So I just used the listAction in the controller, check if coordinates are there and if not call the Google API (and send an email if the Google API does not give a coordinate back).
In another case where the new record comes from a frontend plugin and I had to do something with this data I used the createAction in the Controller. (I am not sure if the createAction is also called when the record is created from the backend.)