Alfresco Activiti Workflow: How to show popup dialog (message box) confirm in button? - popup

I define own outcome-contraint for in workflow-model same as (File: test-model.xml):
<constraints>
<constraint name="my:myOutcomeOptions" type="LIST">
<parameter name="allowedValues">
<list>
<value>Approve</value>
<value>Reject</value>
</list>
</parameter>
</constraint>
</constraints>
And custom sequence-flows to workflow definition (File: test.bpmn20.xml):
<exclusiveGateway id="exclusiveGateway1"</exclusiveGateway>
<sequenceFlow id="flow3" name="Rejected" sourceRef="exclusiveGateway1" targetRef="Rejected">
<conditionExpression xsi:type="tFormalExpression"> <![CDATA[${test_a1approvecount < test_a2approvecount}]]> </conditionExpression>
</sequenceFlow>
I want to when I click button "Reject" showing popup confirm and after click button in popup confirm (OK and Cancel) display change to dashboard.
Please help me!
Thank you advance!

try to add this code in function "onClick".
var reviewTaskTransition = document.getElementsByName("prop_my_myOutcomeOptions")[0].value;
if(reviewTaskTransition == "Approve"){
Alfresco.util.submitForm(p_obj.getForm());
} else if(reviewTaskTransition == "Reject"){
Alfresco.util.PopupManager.displayPrompt({
title: "Rejection Popup",
text: "confirm?",
noEscape: true,
buttons: [{
text: "Yes",
handler: function submitRejection() {
Alfresco.util.submitForm(p_obj.getForm());
this.destroy();
}
},
{
text: "no",
handler: function() {
this.destroy();
document.location.reload(true);
},
isDefault: true
},
]
});
}
else{
Alfresco.util.submitForm(p_obj.getForm());
}

This is bit difficult to implement in alfresco.One more thing is you are confusing your self with back end and front end and you are confusing others too.
First things is , bpmn file is the backend stuff so what ever changes you make in that , it will not show pop up in front end.
For your requirement what you need to do is to make the workflow from configuration changes.Below are certain example where you can find the details of how you can customize the form.
https://hub.alfresco.com/t5/ecm-archive/task-done-transition/m-p/125211/thread-id/66680
https://docs.alfresco.com/6.1/references/dev-extension-points-workflow.html
You can google as well ;)

Related

How to reset bound control values efficiently?

I have an "Add New…" screen with multiple sap.m.Input fields. Everything is working. I submit the form and the values are stored in the DB. But once I re-open this "Add New…" screen, I get the form with previously entered values.
Currently, I can solve the issue iterating over all sap.m.Input fields with sap.ui.core.Element, resetting the values:
Element.registry.forEach(el => {
if (el.isA("sap.m.Input") && el.sId.includes(inputFieldsMask)) {
sap.ui.getCore().byId(el.sId).setValue("");
}
});
Where inputFieldsMask is a mask for all input fields of the relevant screen.
As far as I understand, Element.registry.forEach iterates over all controls in the app, therefore I'm not sure that, from a performance point of view, it's an optimal approach to clean up the fields.
Is there a better way to reset input fields from the previously entered values?
There are several ways to reset the control values depending on what kind of approach you took to create the new entry. Generally, we can make use of the following APIs:
Pass the context to the target container.
In case of working with client-side models: targetContainer.bindElement("newItemPath").
Otherwise, call myV2ODataModel.createEntry("/ThatSet", {...}), which returns a new context, and then pass it to targetContainer.setBindingContext(context, "modelName").
This resolves all the relative bindings in the target container.
<user enters some values and submits ...>
targetContainer.unbindElement("modelName") after the edit was successfully stored.
By unbinding element, relatively bound control values are reset automatically.
Example (using client-side model):
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
"sap/base/util/uid",
], (XMLView, JSONModel, createPseudoUniqueID) => XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc" height="100%">
<App xmlns="sap.m">
<Page backgroundDesign="List" title="Resetting inputs via client-side Model and Context">
<headerContent>
<Button id="addBtn" text="Add Item" type="Emphasized" />
</headerContent>
<List id="myList" growing="true" items="{
path: '/myItems',
key: 'key',
templateShareable: false
}">
<StandardListItem title="{value}" info="Key: {key}"/>
</List>
</Page>
<dependents>
<Dialog id="myDialog"
icon="sap-icon://ui-notifications"
title="New Item"
draggable="true"
class="sapUiResponsiveContentPadding"
>
<Input id="myInput"
placeholder="<New value>"
valueLiveUpdate="true"
value="{
path: 'value',
type: 'sap.ui.model.type.String',
constraints: {
minLength: 1
}
}"
/>
<beginButton>
<Button
text="Submit"
enabled="{= !!%{value} && !%{messages>/}.length}"
/>
</beginButton>
</Dialog>
</dependents>
</App>
</mvc:View>`,
models: {
undefined: new JSONModel({
"myItems": [],
}),
"messages": sap.ui.getCore().getMessageManager().getMessageModel()
},
afterInit: function() {
sap.ui.getCore().getMessageManager().registerObject(this, true);
this.byId("addBtn").attachPress(handleAddPress.bind(this));
this.byId("myInput").attachSubmit(handleSubmit.bind(this));
this.byId("myDialog").setEscapeHandler(onESCPress.bind(this))
.attachAfterClose(onAfterClose.bind(this))
.getBeginButton().attachPress(handleSubmit.bind(this));
function handleAddPress(event) {
const dialog = this.byId("myDialog");
const listBinding = this.byId("myList").getBinding("items");
listBinding.suspend(); // Do not update the list yet
this._currentItems = this.getModel().getProperty("/myItems"); // temp in case user cancels
dialog.getModel().setProperty("/myItems", this._currentItems.concat({})); // new empty item
dialog.bindElement("/myItems/" + listBinding.getLength()); // enable data synchronization via TwoWay binding
dialog.open();
}
function onESCPress(promise) {
const model = this.getModel();
model.setProperty("/myItems", this._currentItems, /*context*/null, /*async*/true);
return promise.resolve(); // continue closing dialog
}
function onAfterClose(event) {
handleAfterClose(event.getSource(), this.byId("myList").getBinding("items"));
}
function handleAfterClose(dialog, listBinding) {
dialog.unbindElement(); // reset data
dialog.setBusy(false);
listBinding.resume();
}
function handleSubmit() {
const dialog = this.byId("myDialog");
if (!dialog.getBeginButton().getEnabled()) return; // something is wrong
dialog.setBusy(true);
if (!this._isStillRequesting) {
this._isStillRequesting = true;
/* send request */setTimeout(mySuccessHandler.bind(this), 3000)
};
}
function mySuccessHandler(newKeyFromServer = createPseudoUniqueID()) {
const dialog = this.byId("myDialog");
this._isStillRequesting = false;
if (!dialog.isOpen()/* request was aborted e.g. by pressing ESC */) {
return; // exit early
}
const context = dialog.getBindingContext();
const value = context.getProperty("value");
dialog.getModel().setProperty(context.getPath("key"), newKeyFromServer);
dialog.close();
sap.ui.require([
"sap/m/MessageToast"
], MT => window.requestAnimationFrame(() => MT.show(`${value} created`)));
}
},
}).then(view => view.placeAt("content"))));
<script id="sap-ui-bootstrap" src="https://ui5.sap.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core,sap.m"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-xx-waitForTheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
As explained above, binding and unbinding element also applies to server-side models such as v2.ODataModel.
Benefits
✅ Reduced overload: no need to iterate over all existing controls. Reset only those automatically that need to be reset.
✅ Control agnostic: does not rely on control specific APIs such as myInput.setValue, mySwitch.setState, etc..
✅ Reduced maintenance costs: no need to maintain list of model properties in controller that application needs to reset manually.
Best practice is to use a model to store your application data and to bind any input field to that model. I added an example here. For the sake of simplicity the model data is cleared when the button is pressed.
In a real world application you would place any setup of the model to the onRouteMatched handler to ensure that the data is in an initial state.
onRouteMatched : function(event) {
this.getView().getModel().setData({
"firstName": "",
"lastName": ""
});
}
Bind all your control values to a model. Then reset this model after you've successfully saved the data.
Example:
control1.bindProperty("value", "/controlValues/control1Value"); // Binding
// control1.bindProperty("value", "/controlValues/name");
// <Input value="{/controlValues/name}" /> // <-- ideal binding in xml view
this.getView().getModel().setProperty("/controlValues", this.resetFormData()); // Clear Model
resetFormData: function () {
var emptyControlValues = {
"control1Value": "", // "name": "", <-- bind to control
"control2Value": 0, // "age": 0,
"control3Value": "", // "address": "",
"control4Value": "" // "tel": ""
};
return emptyControlValues;
};

Is it possible to show a message when app downloads and updates the latest code using ionic deploy?

I use the auto update method to update the app using an ionic pro, The problem is when there is a slow internet connection, The app takes more time to update the app, The splash screen is shown a long time.
Users think that there is a problem in the app and it hangs at the splash screen.
Is there any way to so show a message while updating the app at splash screen?
At least the user will know that the app is being updated.
<plugin name="cordova-plugin-ionic" spec="5.3.0">
<variable name="APP_ID" value="xxxxxx" />
<variable name="CHANNEL_NAME" value="Production" />
<variable name="UPDATE_METHOD" value="auto" />
<variable name="UPDATE_API" value="https://api.ionicjs.com" />
<variable name="MAX_STORE" value="2" />
<variable name="MIN_BACKGROUND_DURATION" value="30" />
</plugin>
I don't think it is possible to show updating on splash screen. but it is possible to show updating processing. here is full code for you.
Pro.deploy.checkForUpdate().then((update) => {
console.log(update);
if (typeof update !== 'undefined') {
if (update.available) {
let alert = self.alertCtrl.create({
title: 'Update Available',
message: 'There is an update available. Would you like to get it?',
buttons: [
{
text: 'Cancel',
role: 'cancel'
},
{
text: 'Ok',
handler: () => {
this.performManualUpdate();
}
}
]
});
alert.present();
}
}
});
async performManualUpdate() {
try {
let loader = this.loadingCtrl.create({
content: "Updating...",
});
loader.present();
await Pro.deploy.downloadUpdate((progress) => {
this.downloadProgress = progress;
})
await Pro.deploy.extractUpdate();
await Pro.deploy.reloadApp();
loader.dismiss();
} catch (err) {
console.log(err);
}
}

Getting a dialog on click of Edit Button on admin-on-rest

I am working on an application using admin-on-rest framework. For editing an entry on a Resource we provide XXXEdit, XXXShow, XXXCreate props to it. My requirement is that when I click on an Edit button in List view on any entry I should get a Dialog box with the parameters in XXXEdit instead of going to a new page. I tried doing this by using a Dialog in XXXEdit component
<Edit title={<RoleTitle />} {...props}>
<SimpleForm>
<Dialog
title="Dialog With Actions"
actions={actions}
modal={false}
open={true}
>
<TextInput source="id" />
<TextInput source="name" validate={required} />
.
.//some more fields
</Dialog>
</SimpleForm>
</Edit>
I get errors like The TextInput component wasn't called within a redux-form
If I use a DisabledInput then I get an error cannot read value of undefined
How do I go on with this?
I do not think you can use Simpleform for this. You will need to create a custom Form using Redux-Form. Look at the bottom answer that documents the final answer.
This might help you
How to richly style AOR Edit page
Instead of creating a page. You are creating a component that connects to the Redux state and displays as a dialog box.
I tried to resolve this using HOC and react-router.
I created a button using AOR button and provided a containerElement
containerElement={
<Link
key={record.id}
to={{
...{
pathname: `${basePath}/${encodeURIComponent(record.id)}`
},
...{ state: { modal: true } }
}}
/>
}
I created a route like this where DialogRoleEdit is an AOR edit component wrapped with a dialog HOC below .
<Route
exact
path="/roles/:id"
render={routeProps => {
return !!(
routeProps.location.state && routeProps.location.state.modal
) ? (
<Restricted authClient={authClient} location={routeProps.location}>
<div>
<RoleList resource={"roles"} {...routeProps} />
<DialogRoleEdit resource={"roles"} {...routeProps} />
</div>
</Restricted>
) : (
<Restricted authClient={authClient} location={routeProps.location}>
<RoleEdit resource={"roles"} {...routeProps} />
</Restricted>
);
}}
/>
Finally an HOC
handleClose = () => {
this.props.history.goBack();
};
render() {
const actions = [
<FlatButton label="Cancel" primary={true} onClick={this.handleClose} />
];
return (
<Dialog>
<WrappedComponent/>
</Dialog>
)
}
We need to provide edit prop for this resource in App.js
edit={DialogUserEdit}

How to close PopUp window in Liferay 6.2?

I am using Liferay UI for popup window in Liferay 6.2. I am getting the pop up but i can not close it.Why it is not working Liferay 6.2.
Below is my code which is written on parent page:
AUI().ready(function(A) {
AUI().use('aui-dialog', 'aui-io', function(A) {
var url = '<%=testPopupURL.toString()%>';
Liferay.Util.openWindow(
{
dialog: {
cache: false,
width:800,
modal: true
},
id:'<portlet:namespace/>shahbaj',
uri: url
}
);
Liferay.provide(
window,
'<portlet:namespace />closePopup',
function(popupIdToClose) {
var A = AUI();
alert(popupIdToClose);
A.DialogManager.closeByChild('#' + popupIdToClose);
},
['aui-base','aui-dialog','aui-dialog-iframe']
);
});
});
Below code is pop-up page content:
<aui:button name="YES" value="YES" onClick="javascript:yes();"/>
<aui:script>
function yes(){
alert('pop');
Liferay.Util.getOpener().<portlet:namespace />closePopup('<portlet:namespace />shahbaj');
}
</aui:script>
Please help me out!!
Add a Cancel / Close button with following script in your jsp.
<input type="button" onclick="hidePopup();" value="Cancel" />
function hidePopup(){
AUI().ready('aui-dialog', function(A){
A.DialogManager.hideAll();
});
}
This worked!!
AUI().ready(function(A) {
AUI().use('aui-dialog', 'aui-io', function(A) {
var url = 'http://localhost/url';
Liferay.Util.openWindow(
{
dialog: {
cache: false,
width:800,
modal: true
},
id:'shahbaj',
uri: url
}
);
Liferay.provide(
window,
'closePopup',
function(popupIdToClose) {
var dialog = Liferay.Util.getWindow(popupIdToClose);
dialog.destroy(); // You can try toggle/hide whatever You want
},
['aui-base','aui-dialog','aui-dialog-iframe']
);
});
});
Simpler Solution
A much simpler solution is to use the close-panel class name.
<aui:button cssClass="close-panel" type="cancel" value="close" />
No additional JavaScript required.
I am working with Liferay 7.2 and I have used the next code in JavaScript:
Liferay.fire('closeWindow',{id:'idPopup'});
in your case idPopup = 'portlet:namespace/shahbaj'
Sorry I dont speak english very good

TinyMCE plugin in umbraco

I'm trying to add a custom button for umbraco richtext datatype, so i made a simple plugin for TinyMCE... But i cant seem to get it working, it shows up in the datatype, but not when i open the editor for some page...
//File: umbraco_client/tinymce3/plugins/addarrowheader/editor_plugin_src.js
//Same content in editor_plugin.js (just minified)
(function () {
tinymce.create('tinymce.plugins.mceAddArrowHeader', {
init: function (ed, url) {
ed.addCommand('addHeader', function () {
alert('hello!');
});
ed.addButton('addArrow', { title: 'DoAdd', image: '/images/editor/umbracoTextGen.gif', cmd: 'addHeader' });
},
getInfo: function () {
return {
longname: 'mceAddArrowHeader',
author: 'Bekker',
authorurl: 'Eksponent.com',
infourl: 'none',
version: tinymce.majorVersion + "." + tinymce.minorVersion
};
}
});
// Register plugin
tinymce.PluginManager.add('mceAddArrowHeader', tinymce.plugins.mceAddArrowHeader);
})();
Added following to tinyMceConfig.config (/config/ folder)
//in <commands>
<command>
<umbracoAlias>mceAddArrowHeader</umbracoAlias>
<icon>images/editor/spellchecker.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="mceAddArrowHeader">addarrowheader</tinyMceCommand>
<priority>76</priority>
</command>
//In <plugins>
//just using spellchecker.gif for test purpose, no custom icon yet...
<plugin loadOnFrontend="false">addarrowheader</plugin>
It seemed to be a matter of wrong plugin folder naming...
Didnt know that it had an impact, but renaming the folder to same name as the plugin (mceAddArrowHeader) solved the problem.