How can I develop my own components for my project?

Edit me

There is a file you can add to enhance your project with your own components.

The manifest

Every project has a manifest to list all files needed for it to work properly. It’s a JSON provided by the server (Voozanoo4) and it look like this:

{
	"structure": {
		"version": 123,
		"token": "ABC"
	},
	"files": {
		"build": {
			"version": 2,
			"token": "CBA"
		}
	}
}

The key “structure” is mandatory. All others files are listed into the section “files”. This section is optional and some of the sub-keys are reserved.

  • “build” for the specific code.
  • “style” to change the presentation.
  • “icon” for a dedicated icon on the project’s list.
  • “translation” (JSON) to add some translation

Any other file listed in the “files” section will be downloaded on the device but will not be used automatically. They are assets for developers. Example with a jpg:

// Manifest
{
	"structure": [...],
	"files": {
		"cloudAndSky": {
			"version": 1,
			"token": "CBA"
		}
	}
}

// Every component loaded (by using customs) have the function in their props "getAssetPath"
// getAssetPath return the local path on the device
const sPathImage = getAssetPath('cloudAndSky');

// then in the render
return <Image source={{uri: `file://${sPathImage}`}}/>

How can i inject some of my code in the project?

Some hooks are implemented natively in the Voozanoo Application. Some others can be added with Epicraft.

Add a widget

For this example, we want to use a specific component named “AwesomeImage” and passed to it the url “http://awesome/logo.png”.

Key - value

Key: epimob.widget Value: “AwesomeImage”

Key: epimob.widget.option.url Value: “http://awesome/logo.png”

Complete JSON

Key: epimob.widget Value:

{
  component: 'AwesomeImage',
  option: {
    url: "http://awesome/logo.png"
  }
}

Mixed

Key: epimob.widget Value: “AwesomeImage”

Key: epimob.widget.option Value:

{
  url: "http://awesome/logo.png"
}

Add an addon to a field

You can add a little something to a field. For example, you can add a small button to the right side of the field.

Key: epimob.widget.addon Value: “MySmallButton”

Key: epimob.widget.addon.position Value: “after”

Key: epimob.widget.addon.option.label Value: “click me”

There are three position available: before, after and around.

Props passed on each components

Each component instanced by a custom build receive some props:

Name Type
rowId string
project object
datasets array
history array
datasetManager object
changeToHome function
changeToHistory function
changePage function
popPage function
resendMessage function
saveExtraData function
loadExtraData function
getAssetPath function
requestHub function
sendNotifications function
confirmDialog function
translate function
scanBarCode function
dangerouslyDispatchAction function

A bulk has some more props:

Name Quick description Type
returnKeyType   string
onSubmitEditing   function
node bulk node object
dataset current dataset of the page object
option option of the custom object

Basic

rowId string

Id of current entry in the dataset.

project object

Instance of the loaded project.

{
	id: 1,
	// username of the user
	sUsername: 'TestUser',
	sName: 'Sample project',
	sDescription: 'project for tests.',
	oOthers: {},
	oManifest: {},
	aDatasets: [],
	aListenerDatasets: [],
	oExtra: {
		aData: []
	}
}

datasets array

List of all datasets of the project. API of a dataset here

history array

List of messages sent to the hub.


// one item in history
{
	sId: 123,
	sType: 'XHR',
	sStatus: 'pending',
	sDestination: 'http://prohub.voozanoo.net/Dataset/token/ABCD1234',
	sMessage: '{...stringified dataset}',
	sDatasetName: 'patient',
	aRowsIds: [1, 2, 4],
	aBackupsRows: [{...rowdata}, {...rowdata}, {...rowdata}],
	sDate: 1503934576453,
	sUserId: 'testUser',
	sProjectId: 'testProject',
	sProjectName: 'Test Project 01'
}

datasetManager object

changeToHome function

Return to the welcome page of the project.

changeToHome();

changeToHistory function

Open the history page for the project.

changeToHistory();

changePage function

Open a page (or return to previous if already opened).

// open a page with the id of an entry associated to the dataset of the page
changePage(sIdPage, sRowId);

// open a new page for a new entry (generate a uniqId for the row)
changePage(sIdPage);

popPage function

“Pop” the current page to return to the previous (back button).

popPage();

Others

resendMessage function

Re-send a message which has failed to be sent before.

resendMessage('a1b2c3');

saveExtraData function

Save data which cannot fit in a dataset.

// must be able to serialized (no function)
const oExtraData = {
	name: 'jack',
	lastTimeChecked: Date.now(),
	lastRoleUsed: ['admin', 'user']
};

// generate a uniqId for the data and save it
saveExtraData(oExtraData);

// use the given id to save the data
saveExtraData(sExtraId, oExtraData);

loadExtraData function

Load extra-data in the project (check project). This function is asynchrone and doesn’t return anything, the loaded data has to be checked in the project the next it is updated.

const sExtraId = 'abc';

loadExtraData(sExtraId);

// an object can be passed to filter results
loadExtraData(sExtraId, {name: 'jack'});

loadExtraData({name: 'jack'});

// result will be available when loaded that way:
this.props.project.oExtra.aData
.forEach(oExtraData => {
	// {sId: 'abc', oData: {name: 'jack', lastTimeChecked: 1503840500789, lastRoleUsed: ['admin', 'user']}}
	console.log(oExtraData);
});

getAssetPath function

Return the local path of an asset downloaded by the manifest.

// shorted manifest
{
	structure: {},
	files: {
		logoPatient: {
			version: 1,
			token: ABC
		}
	}
}

// return the localpath ([PATH_IN_DEVICE]/logoPatient)
getAssetPath('logoPatient');

requestHub function async promise

Promise XHR request on an endpoint of VooHub.

handleRequestHub('Environment/list')
.then(oResponse => {
	console.log(oResponse.responseText);
})
.catch(oError => console.error);

sendNotifications function

Send a notification for a feedback user. Only two type exist for now and only one work on iOS.

// open an alert modal
sendNotifications('Something wrong!', 'alert')

// use a android toast (small round grey bar at the bottom of the screen with a short text)
// only work on android
sendNotifications('Something wrong!')

confirmDialog function

(http://facebook.github.io/react-native/releases/0.47/docs/alert.html#alert)

Open a confirmation dialog (modal).

const aButtons = [
	{
		text: translate('Cancel'),
		onPress: () => console.log('Cancel Pressed'),
		style: 'cancel'
	},
	{
		text: translate('OK'),
		onPress: () => console.log('OK Pressed')
	}
];

confirmDialog(sMessage, sTitle, aButtons);

translate function

Translate the messaged passed in the language of the mobile.

// return 'Chargement' with a french device
translate('Loading');

scanBarCode function

Not implemented yet.

dangerouslyDispatchAction function

Developers should explicitly state their intent when performing “unsafe” operations.

Permet aux développeurs de déclencher directement des fonctionnalités du noyau sans passer par un objet-interface.