API
csApiSession
Use the csApiSession module to access methods to get assets, execute queries or command handlers.
- As the name says, it uses the current user session so you don’t need to care about that
- You do not need to add csApiSession to your module dependencies, it’s provided by framework by default
- To use it, simply inject
csApiSession
in the function you need it
Please note that
csApiSession
is deprecated and replaced with ApiService in Angular 2+. WhencsApiSession
is used, it works by calling theApiService
under the hood.
csApiSession.execute(commandId, method, data)
It executes the method of a command with provided data.
Parameters:
- commandId {String} - Command id
- data {Object}
- method {String} - Method name
It returns:
- {Promise}
|
csApiSession.execute(id, data)
It executes a command with provided data.
Parameters:
- commandId {String} - Command id
- data {Object}
It returns:
- {Promise}
|
csApiSession.asset.get()
It gets an asset by id or multiple assets if an array of ids is given.
Parameters:
- id {number|Array} - Asset ID(s)
- options - possible options are:
- version (when getting single asset)
- currversion (when getting single asset)
- ccn (when getting single asset)
- view: {modelFormat: ‘update’|‘logical’, traits:‘trait1,trait2,…’, trafo: view-model-transformation}
It returns:
- {Promise}
|
csApiSession.asset.query()
Query for assets.
Parameters:
- query - Query object
It returns:
- {Promise}
|
csApiSession.asset.liveQuery()
Query for assets with continuous updates, it sends updates as promise notify and returns no values in promise resolve.
Parameters:
- query - Query object
- destructible - Object which provides ‘onDestroy’ callback. Live query is cancelled when destructible is destroyed.
It returns:
- {Promise}
|
csApiSession.masterdata.lookup()
Lookup on master data values. No matter how many records are returned by the command, the results are always provided as an array.
Parameters:
- lookup - Object which specify conditions
It returns:
- {Promise}
|
csApiSession.masterdata.singleValueLookup()
Lookup on master data values. If the result contains only one record, the return record array is omitted and the single result is directly provided as an object.
Parameters:
- lookup - Object which specify conditions
It returns:
- {Promise}
|
csApiSession.permission.checkAssetIndependentPermission()
Parameters:
permissionKey
String that identifies the permission
It returns:
- {Promise}
|
csApiSession.permission.checkAssetPermission()
Parameters:
permissionKey
String that identifies the permissionassetRef
- Asset reference
It returns:
- {Promise}
|
csApiSession.relation.add(assetId, relatedAssetId, relationType, direction)
It creates a new relation with a specified direction. Please note that you either are allowed to pass a set of ids for parentId
or for childId
. It is forbidden to pass an array for both parameters.
Parameters:
- parentIds {Number|Array }
- childIds {Number|Array }
- reltype {String}
- direction {String} relation direction
It returns:
- @returns {Promise}
|
csApiSession.relation.create(parentIds, childIds, reltype, isFeatureRef)
It creates a new relation. Please note that you either are allowed to pass a set of ids for parentId
or for childId
. It is forbidden to pass an array for both parameters.
Parameters:
- parentIds {Number|Array }
- childIds {Number|Array }
- reltype {String}
- isFeatureRef {Boolean}
It returns:
- @returns {Promise}
|
csApiSession.relation.delete(parentId, childId, reltype, isFeatureRef)
It removes and existing relation.
Parameters:
- parentIds {Number|Array }
- childIds {Number|Array }
- reltype {String}
- isFeatureRef {Boolean}
It returns:
- @returns {Promise}
|
csApiSession.resourceassets.lookup(filter)
Queries resource assets filtered by a given filter condition.
Parameters:
- filter {Object} - Filter object. The following filter properties can be set:
- sourceAssetRef : Key of the source asset, on which the resource asset (e.g. transformation) will be applied (optional). Only resource assets, whose source filter matches the given asset, will be included into the result.
- targetAssetRef : Key of the target asset, on which the resource asset (e.g. transformation) will be applied (optional). Only resource assets, whose target filter matches the given asset, will be included into the result.
- usage: Usage key of the resource asset (optional). Examples: “censhare:indesign-content-transformation”, “censhare:chart-data-transformation”, “censhare:content-transformation”
- assetType: Exact type of the resource asset (optional). Sub types are not included.
- mimetype: Mimetype of the transformation result (only for transformation resource assets) (optional).
- format: Format key of the transformation result (only for transformation resource assets) (optional).
It returns:
- {Promise} The promise is fulfilled with a set of resource assets matching the filter condition. The result structure looks like this:
|
|
csApiSession.session.getLocale()
It returns the locale for the current API session.
csApiSession.session.getTimezone()
It returns the time zone for the current API session.
csApiSession.session.getUserAssetReader()
It returns a read for the user asset data.
It returns:
- csReader
|
csApiSession.session.getUserId()
It returns the user party table id.
csApiSession.session.resolveUrl(url)
It returns a qualified HTTP URL for either a censhare URL (censhare://…) or a path relative to the base of the application (/img/no-image.jpeg)
Parameters:
- url A REST or censhare url
It returns:
- url that could be used
|
csApiSession.workspace.getUserPreferences()
It returns:
- {Promise} Current user preferences
|
csQueryBuilder
It provides an API to generate a query object for csApiSession.asset.query() and csApiSession.asset.liveQuery() methods.
- Include csQueryBuilder to module dependencies
csQueryBuilder
has it’s own methods, but also supports csQueryBuilder.Node
interface, so has all methods provided by csQueryBuilder.Node
.
|
build()
It generates a query object.
It returns:
- {QueryObject}
setLimit(limit)
It sets query limit. Limit specifies maximal amount of assets to be returned by query.
Parameters:
- limit {Number}
setOffset(offset)
Offset of a query is used to support pagination. Using query limit and offset, amount and range of returned asset could be specified.
Parameters:
- offset {Number}
setQueryParamFilterValue(queryParamFilter)
It sets custom value for csQueryParamFilter. csQueryParamFilter is used to filter asset behaviours. The Behavior with queryParamFilter will be included into assets which was queries with a query with the same queryParamFilter.
Parameters:
- queryParamFilter {String}
order()
It creates or returns existing one csQueryBuilder.Order object. Is used to specify query order and grouping.
It returns:
- {csQueryBuilder.Order}
view()
It creates or returns existing one View object. Is used to specify query view: view transformation, traits which will be included, view name and etc.
It returns:
- {csQueryBuilder.View}
csQueryBuilder.Node
Node object is used to set conditions for a query.
condition(name, value)
It creates condition to check if feature is equal to provided value. Can be used only for features which can have Null value. If a few conditions are added to the query, AND logic is used to combine them.
Parameters:
- name {String} - Name of a feature
- value {String} - Value of the feature
condition(name, op, value)
It creates condition to check feature value using operator provided. Can be used only for features which can have Null value. If a few conditions are added to the query, AND logic is used to combine them.
Parameters:
- name {String} - Name of a feature
- value {String} - Value of the feature
- op {String} - Operator. Possible values for operator: “=”, “<”, “<=”, “>”, “>=”, “!=”, “like”, “IN”, “ISNULL”, “NOTNULL”
condition(name)
It creates condition to check if feature is exist. Can be used only for features which can have Null value. If a few conditions are added to the query, AND logic is used to combine them.
Parameters:
- name {String} - Name of a feature
and()
Adds Query Node to existing Node with AND logic, all subnodes and condition of which are combined with AND logic: node AND (cond1 AND cond2).
It returns:
- {csQueryBuilder.Node}
not()
Adds Query Node to existing Node with AND NOT logic: node AND NOT(cond1 AND cond2)
It returns:
- {csQueryBuilder.Node}
or()
Adds Query Node to existing Node with AND logic, all subnodes and condition of which are combined with OR logic: node AND (cond1 OR cond2)
It returns:
- {csQueryBuilder.Node}
relation(direction, type)
Adds relation conditions to existing Node, which is used to search by related assets. Relation condition and subcondition are added using AND logic to existing node.
Parameters:
- direction {String} - relation direction
- type {String} - relation type
|
It returns:
- {csQueryBuilder.Node}
csQueryBuilder.Order
Allows to set order for result.
|
orderBy(property, isAssending)
It sets an order for result assets
csQueryBuilder.View
Allows to set custom representation for assets.
|
setTransformation(assetKey)
It sets a XSLT transformation asset for a query result, which will transform standard asset representation to a new one.
“censhare:cs5.query.asset.list” transformation is used in censhare to add required information for standard item renderers.
setViewName(viewName)
It sets workspace view name, which allows to specify additional data, which should be added into asset structure.
Use csViewNameResolver
to get appropriate viewName
for asset representation.
setModelFormat(model)
It sets format of asset View Model. If no format is set, logical model of the asset will be returned. Set “update” as a model format to get asset Update model.
csContextProvider
getAssetId()
It returns the asset id of the context.
getApplicationNames(): string[]
It returns the names of the applications supported by this context.
getBasicAssetApplication()
It returns the com.censhare.api.applications.asset.BasicAssetApplication
instance
getLiveApplicationInstance(name)
It returns a reader that contains the requested application instance.
hasApplication(name)
It returns if the given application is supported by the context. This is faster than searching in the array provided by getApplicationNames, because a simple has based lookup is performed.
hasBasicAssetApplication()
It returns if the com.censhare.api.applications.asset.BasicAssetApplication
is supported by the context.
csQueryBuilder
It provides an API to generate a query object for csApiSession.asset.query() and csApiSession.asset.liveQuery() methods.
- Include csQueryBuilder to module dependencies
csQueryBuilder
has it’s own methods, but also supports csQueryBuilder.Node
interface, so has all methods provided by csQueryBuilder.Node
.
|
build()
It generates a query object.
It returns:
- {QueryObject}
setLimit(limit)
It sets query limit. Limit specifies maximal amount of assets to be returned by query.
Parameters:
- limit {Number}
setOffset(offset)
Offset of a query is used to support pagination. Using query limit and offset, amount and range of returned asset could be specified.
Parameters:
- offset {Number}
setQueryParamFilterValue(queryParamFilter)
It sets custom value for csQueryParamFilter. csQueryParamFilter is used to filter asset behaviours. The Behavior with queryParamFilter will be included into assets which was queries with a query with the same queryParamFilter.
Parameters:
- queryParamFilter {String}
order()
It creates or returns existing one csQueryBuilder.Order object. Is used to specify query order and grouping.
It returns:
- {csQueryBuilder.Order}
view()
It creates or returns existing one View object. Is used to specify query view: view transformation, traits which will be included, view name and etc.
It returns:
- {csQueryBuilder.View}
csQueryBuilder.Node
Node object is used to set conditions for a query.
condition(name, value)
It creates condition to check if feature is equal to provided value. Can be used only for features which can have Null value. If a few conditions are added to the query, AND logic is used to combine them.
Parameters:
- name {String} - Name of a feature
- value {String} - Value of the feature
condition(name, op, value)
It creates condition to check feature value using operator provided. Can be used only for features which can have Null value. If a few conditions are added to the query, AND logic is used to combine them.
Parameters:
- name {String} - Name of a feature
- value {String} - Value of the feature
- op {String} - Operator. Possible values for operator: “=”, “<”, “<=”, “>”, “>=”, “!=”, “like”, “IN”, “ISNULL”, “NOTNULL”
condition(name)
It creates condition to check if feature is exist. Can be used only for features which can have Null value. If a few conditions are added to the query, AND logic is used to combine them.
Parameters:
- name {String} - Name of a feature
and()
Adds Query Node to existing Node with AND logic, all subnodes and condition of which are combined with AND logic: node AND (cond1 AND cond2).
It returns:
- {csQueryBuilder.Node}
not()
Adds Query Node to existing Node with AND NOT logic: node AND NOT(cond1 AND cond2)
It returns:
- {csQueryBuilder.Node}
or()
Adds Query Node to existing Node with AND logic, all subnodes and condition of which are combined with OR logic: node AND (cond1 OR cond2)
It returns:
- {csQueryBuilder.Node}
relation(direction, type)
Adds relation conditions to existing Node, which is used to search by related assets. Relation condition and subcondition are added using AND logic to existing node.
Parameters:
- direction {String} - relation direction
- type {String} - relation type
|
It returns:
- {csQueryBuilder.Node}
csQueryBuilder.Order
Allows to set order for result.
|
orderBy(property, isAssending)
It sets an order for result assets
csQueryBuilder.View
Allows to set custom representation for assets.
|
setTransformation(assetKey)
It sets a XSLT transformation asset for a query result, which will transform standard asset representation to a new one.
“censhare:cs5.query.asset.list” transformation is used in censhare to add required information for standard item renderers.
setViewName(viewName)
It sets workspace view name, which allows to specify additional data, which should be added into asset structure. Use csViewNameResolver
to get appropriate viewName
for asset representation.
setModelFormat(model)
It sets format of asset View Model. If no format is set, logical model of the asset will be returned. Set “update” as a model format to get asset Update model.
csChannelSniffer
The channel sniffer is a module that allows us to directly monitor the communication between the censhare Web client running on a browser and censhare server.
Reasons behind channel sniffer
Due to the fact that we use a WebSocket-based channel to communicate between the browser and the server, we are unable to directly monitor the traffic as it’s done in the traditional HTTP request-based applications (eg. using the ‘network’ tab from the browser’s developer tool). Moreover, the channeled data are compressed, which causes all webSocket-monitoring tools to display binary gibberish.
The channel sniffer allows us to log the data that are sent through the channel directly in browser’s console, just before they are compressed (requests) or inflated (responses).
The Sniffer can be used for example to monitor and check the validity of data that are sent/received from the application, without the need to interfere with the application code.
Using the channel sniffer
To use the channel sniffer, you need to:
- activate the developer mode in censhare web (enter the user menu via clicking on the user info on top right corner of the screen, choose ‘About censhare web’ option and alt+click the close button in displayed about dialog).
- activate the channel sniffer by clicking on the newly displayed developer menu (wrench icon), that appears next to the user info menu, and choose the ‘Toggle Channel Sniffer’ option.
- open the console, in the browser’s developer tools
- notice the request/response messages as you are using the application
Interpreting sniffer messages
csService
createObservable<T>(initialValue: T): IObservable<T>;
It creates a csObservable
instance with initial value of type T.
bindToScope(scope, propName: string, observable, mapper): void;
Binds csObservable
or `csReader the scope. Optionally mapper function can be provided, which can transform csObservable or csReader value to any scope object.
For the given scope and property, the given observable is bind in a way that:
1. If the value of the observable changes, the value stored inside of the scope is updated.
2. If the scope is destroyed, the listener registered on the observable is automatically removed.
Hence, this method is the preferred way to automatically let a scope property continually reflect the value of an observable.
Please notice that the method checks if there is already a value stored in the property of the scope.
Parameters:
- scope {ng.IScope} - scope
- propName {string} - scope property name
- observable {IReader |IObservable } - observable or reader
- mapper {(reader: IReader ) => any} - optional mapper function. Receives an observable reader as a parameter.
|
createIt executesAsyncLastCallWrapper(a: any): any;
Create a wrapper for multiple calls of the function and executes the last call asynchronously.
If a function f is called with the invoke of angular multiple times, then for f’ = createIt executesAsyncLastCallWrapper(f) it holds calls and executes only the last one.
Parameters:
- f {function} - any function
Return:
- {function} - wrapped function
|
createIt executesAsyncLastCallWrapperNative(a: any): any;
Create a wrapper for multiple calls of the function and executes the last call asynchronously without triggering digest cycle for the document.
csUploadManagerService
This section describes the implementation of the file upload in censhare Web. The file upload is used to create assets or overwrite the Master file of an asset.
Services
There are two services available for the file upload:
csUploadsManager
with the TypeScript classUploadManagerService
csFileUploadService
with the TypeScript classFileUploadService
The actual upload process of both is identical, the differences are as follows:
csFileUploadService
includes the duplicate check (wizard). This should be default for creating assets. Users can however disable it in their preferences so that the service will be skipped and delegated to csUploadsManager
. This service implements the main upload logic.
Usage
General usage with relation creation and duplicate check (remember: the duplicate check can be disabled by the user):
Example: Create asset dialogconst
uploadFileConfig: any = {};
if
(context.relation) {
uploadFileConfig.relation = {
baseAssetId: context.parentAsset,
relationType: context.relation.key,
direction:
this
.csAssetUtil.invertDirection(context.relation.direction),
sortable:
false
};
}
csFileUploadService.uploadFiles(files, uploadFileConfig);
Doing the duplicate check manually without the wizard:
Example: For a single file you can do the duplicate check without the wizardif
(csFileUploadService.isDuplicateCheck()) {
csFileUploadService.checkFileDuplicate(file).then(
(result) => {
if
(result.assetId !==
0
) {
// found duplicate, handle it
}
else
{
// no duplicate, just upload
uploadNewFile();
}
}
);
}
else
{
uploadNewFile();
}
const
uploadNewFile = () => {
return
csFileUploadService.doUpload(file, { command: { key: cmdFromFile, params: params } });
}
Direct upload without duplicate check:
Example: Upload Master file
csUploadsManager.addNewUploads(files).then(
(value) => {
updateModel(value.assetId);
},
(error) => {
csNotify.warning(
'csCommonTranslations.fileUploadFailed'
, error);
},
(progress) => {
this
.uploadProgressValue = progress;
}
);
File size check before upload:
checkMacimumSize
is used to check a file’s size before upload, to ensure that its size is smaller than the specified limit in the system properties. Files with bigger size than the defined limit are excluded, a notification shows the names of the excluded files and the size limit.public
checkMaximumSize(source: FileList | File | File[]): ng.IPromise<File[]> {
const
defer =
this
.$q.defer<File[]>();
this
.csSystemSettings.getFileUploadSettings().then((sysConfig: ISystemUploadSettings) => {
const
files = FileUploadService.toFileArray(source);
const
length = files.length -
1
;
const
filesExceededLimitNames: string[] = [];
for
(let i = length; i >=
0
; i--) {
if
(files[i].size > sysConfig.maximumSize) {
filesExceededLimitNames.push(files[i].name);
files.splice(i,
1
);
}
}
defer.resolve(files);
if
(filesExceededLimitNames.length >
0
) {
const
maxSizeLimitMsg =
this
.csTranslate.instant(
'csUploadsManager.fileMaxSizeMessage'
,
{
filesNames: filesExceededLimitNames.join(
','
),
maxSize:
this
.csFileSizeService.convert(sysConfig.maximumSize)
});
const
maxSizeLimitTitle =
this
.csTranslate.instant(
'csUploadsManager.filesMaxSizeTitle'
);
this
.csNotify.warning(maxSizeLimitTitle, maxSizeLimitMsg);
}
});
return
defer.promise;
}
Example: Uploading files from the asset chooser
public
addNewUploadsWithFileChooser(multi:
boolean
, command?: string, options = {}): ng.IPromise<any> {
const
deferred =
this
.$q.defer();
this
.openFileChooser(multi, (files) => {
this
.checkMaximumSize(files).then((_files: File[]) => {
if
(_files.length >
0
) {
deferred.resolve([
this
.addNewUploads(_files, command, options)]);
}
});
});
return
deferred.promise;
}
Technical background
Uploading a file or multiple files can be done via drag & drop or using a file chooser. The methods to upload accept a File
object or a FileList
objects which is an array like structure of files. Optionally, a config object can be passed which holds information about which CommandHandler
should process the uploaded files and if relations to other assets should be created. See the section CommandHandlersbelow for more details.
New in this version the creation of temporary upload assets which holds the uploaded data while upload is in progress and are deleted after the final assets are created. This also enables a resume functionality of the upload which will be described in the client section.
The client side
On the client side we make use of the 3rd-party library resumable.js which is able to split a file into smaller pieces called chunks and upload those chunkseparate to the server. Furthermore resumable.js can ask the server if a chunk already exist and skip uploading this chunk. This implements the resume functionality. Also chunks can be uploaded in parallel.
If multiple files are added, they will be put into a queue. A configurable number of consumers will then create the uploads in parallel.
Options for the upload
You can provide optional options which are mainly used on server side for processing the uploaded data.
command
: string - Id of a CommandHandler being used for uploaded data. Default iscom.censhare.api.fileupload.NewAssetFromFile
relation
: object - If you want to create a relation to another asset set the following propertiesbaseAssetId
: number - Id of the asset to relate torelationType
: string - Key of the relation type or feature for asset-refdirection
: string - The relation direction [child | parent | feature | feature-reverse]
Configuration
The configuration defines the settings for resumable.js:
chuckSize
- Size of each chunk in bytessimultaneousUploadChunks
- Number of chunks uploaded in parallel
There are as well the following general settings:
simultaneousUploadFiles
- Number of files uploaded in parallelchunkRetries
- Number of retries if uploading a chunk fails before skipping the upload
The configuration is set on the system asset but can be overwritten by users in their preferences.
Hint for parallel uploads
Uploading in parallel can increase the total upload speed. Of course main limit is the bandwidth but multiple streams could result in using total bandwidth but this also depends on the latency. There’s no general rule how many simultaneous uploads are good but too many reduce the speed. A total number of 10 parallel connection should not be exceeded which mean 2 simultaneousUploadChunks
and 5 simultaneousUploadFiles
, or 3 and 3, etc.
As mentioned, there’s no general rule so I suggest using smaller numbers e.g. 2 and 2 but also try out what works best for you.
Server side
The uploaded uses the Java Servlet FileUploadServlet
to process data. We’re using the apache commons upload library for streaming the data from client to the server. Because multiple uploaded can happen in parallel, there is the ResumableUploadService
singleton to manage the creation, updating of temporary upload assets and calling the final CommandHandler to process the uploaded file. With the uploadId send by the client we can identify the temp upload asset and add the additional file chunks here as storage item. Every chunk will create a new storage item.
If the upload is interrupted (due to server or connection, an existing temp upload asset will be used and already uploaded chunks will be restored so the client don’t have to send them again.
Once all chunks are uploaded, the ResumableUploadService
will execute the configured CommandHandler with an InputStream
that concatenates the single chunks into a single stream.
CommandHandlers
There’re a few CommandHandlers in place to process the uploaded data.
com.censhare.api.fileupload.NewAssetFromFile
which is the default one for creating assets from filescom.censhare.api.dam.assetmanagement.replacemasterstorageitem
to replace the storage item of existing assetcom.censhare.api.command.server.upload
to upload files and provide them to classic server actions
EventEmitter
The EventEmitter
class is defined and exposed by the csEvents
module:
|
All objects that emit events are instances of the EventEmitter
class. These objects expose an .on()
and .once
methods, that allow one or more functions to be registered to named events emitted by the EventEmitter
. Event names should typically be camel-cased strings.
When the EventEmitter
emits an event, all of the functions registered on that specific event are called synchronously.
Registering and triggering of the event
The following example shows a simple EventEmitter
instance with a single listener registered to an event. The .on()
method is used to register listeners, while the .emit()
method is used to trigger the event by specifying the event name as a first function argument, and will return a boolean value whether an event was triggered or not.
|
The EventEmitter
calls all event listeners synchronously in the order in which they were registered, so it is important to ensure the proper sequence of events in order to avoid race conditions or logic errors.
Passing arguments to the listeners
The .emit()
method allows an arbitrary set of arguments to be passed to the event listeners. The first argument is always event name, while all following arguments will be used as arguments of all listeners registered to the event.
|
Handling event only once
When a listener is registered using the .on()
method, that listener will be invoked every time the event is emitted.
Using the .once()
method, it is possible to register a listener that is called only once.
|
Registering listener with context
When a listener is a function without context - prototype
, access to this
will fail with undefined exception
.
|
To fix this error either register the lambda
function:
|
Or use a third argument on the .on()
method, to specify your context:
|
Unregistering the event listener
To unregister the event listener properly, the .off()
method is used.
Method | Description |
---|---|
emitter.off() | It will unregister all event listeners |
emitter.off('eventName') | It will unregister all event listeners from a specific event (e.g. eventName) |
emitter.off('eventName', listener) | It will unregister the event listener from the event that is matching the provided function |
emitter.off('eventName', listener, context) | It will unregister the listeners that are matching the event name, function, context |
emitter.off('eventName', listener, context, once) | It will unregister the listeners that are matching the event name, function, context, once |
Unregister all event listeners
|
Unregister event listeners from one event
|
Unregister only one listener from the event
|
Unregister only event listener matching to provided context
|
Unregister only event listener matching registered with .once()
|
Strict event handling
By using typescript generics we can as well lock the events we want to allow, and typescript will throw an error for any other event.
|
Methods
Method | Description |
---|---|
getEventNames() | It returns all events with registered event listeners |
getListeners(event: string) | It returns all listeners registered to the provided event |
exist(event: string) | It returns a boolean value on whether the listeners are registered to the provided event |
Dialogs
csAssetCreateDialog
- Extended version of
csAssetChooserDialog
- Allows user to choose or create a new asset from 1 dialog
- Contains tabs:
New asset
- create asset using metadata dialogAsset from template
Asset from file
Existing asset
- Provides possibility to hide tabs and set default one
Usage
- Add
csAssetCreateDialog
module to dependencies - Inject
csAssetCreateDialog
to a component - Open the
csAssetCreateDialog
:
|
context
Context object can contain following properties:
title
- defines the dialog titleaddAssetFromTemplateTab
- flag for displaying the “Asset from template” tab.addNewAssetTab
- flag for displaying the “New asset” tab. By default istrue
.addUploadTab
- flag for displaying the “Asset from file” tab. By default istrue
.addAssetTab
- flag for displaying the “Existing asset” tab. By default isfalse
.defaultTab
- active tab index, its default value is 0.defaultTemplate
- the resource key of the Asset Metadata Dialog that should be shown in theNew asset
tab.targetAssetType
- restricts the dropdown and show dialog to a specific asset type.
|
Additionall, csAssetCreateDialog
context can contain properties for the csAssetChooserDialog
which allows to setup how the Existing asset
tab will look like.
csAssetChooserDialog
- Used to choose one or more assets
- Allows to use filters and search
- Can contain configurable tabs
- Returns an array‚ of selected assets in resolved promise
Usage
- Add
csAssetChooserDialog
module to dependencies - Inject
csAssetChooserDialog
to a component - Open the
csAssetChooserDialog
:
|
context
Context object can contain following properties:
singleSelect
- if single selection mode is active, false by defaultrefinements
- array of defined tabs. Could be configured with a query or predefined.- Predefined tabs: “all”, “related_assets”, “currently_editing”, “tasks”, “last_created”, “last_edited”, “pinboard”
- Custom tab is an object, which contains label, key and a query
- It’s possible to mix custom and predefined tabs
- If the property refinements is not defined, it is initialized by the AssetChooser
all
is added by default
|
filter
- a query, which will be applied to all tabs
|
behaviors
- list of behaviors which should appear for asset, empty by defaultallowedFor
- asset type filter, simplified way to set type filter for the dialog.
|
template
- boolean flag, if only templates (‘censhare:asset-flag’ = ‘is-template’) should appear in the dialog
Observables
csObservable
The csObservable
is an implementation of Observer design pattern.
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.
To use csObservable
in your code:
- include
csServices
as a dependency for your module - include censhare type definitions in your module to use csServices interfaces in TypeScript code:
|
- Use
csServices.createObservable(initialValue): IObservable<T>
to create an observable:
Parameters: initialValue {T} - initial value of csObservable
Returns: IObservable
|
csObservable
implements interface csServices.IObservable- Read more about registering listeners in
csReader
Methods
getValue(): T
Returns current value of observable.
setValue(value: T): IObservable<T>
Sets a new value for observable. If the value is different than previous one, all observers are notified.
getReader(): IReader<T>
Returns reader for observable value, which is instance of csReader
.
notify(): void
Notify all listeners even if value wasn’t changed.
destroy(): void
Destroy observable.
|
registerChangeListener() vs registerNativeChangeListener()
Observables have 2 types of listeners:
- listeners which are registered by the
registerChangeListener()
listener - nativeListeners which are registered by the
registerNativeChangeListener()
listener
If an observable has listeners.length > 0, then it will trigger the $apply()
for the document.
If an observable has only nativeListeners, then no digest cycle will be performed.
As $apply()
is a very expensive operation towards performance, make sure to avoid using the registerChangeListener()
when there is no need to update the DOM. When there is need to update only a part of the DOM, use csServides.bindToScope()
. It will bind an observable or a reader of the observable to the scope object:
|
csReader
csReader
provides possibility to read and listen the value of an csObservable.
getValue(): T;
Get the current value of a csObservable
.
registerChangeListener(listener: (value: T) => void, destroyable?: any): void;
It registers the given callback as a listener. If the second parameter is passed, the register will be automatically removed if the destroyable is destroyed, e.g. if the scope is destroyed or for a pageInstance
, if the instance is closed.
Note: When csObservable will get a new value, it will trigger
$apply()
, so update the whole document, if at least one listener was registered.
Prefer to use registerNativeChangeListener()
when $apply()
is not needed. To trigger local updates for changed value use csServides.bindToScope()
which will bind an observable or reader to the scope:
|
Read more about csServides.bindToScope()
Parameters:
- listener - callback to register
- destroyable - destroyable object to remove listener automatically, when destroyable will be destroyed
registerChangeListenerAndFire(listener: (value: T) => void, destroyable?: any): void;
It registers the given callback as a listener and sends notification immediately. The difference with registerChangeListener()
is that after registering the callback immediately receives a notification with current value of the observable.
registerNativeChangeListener(listener: (value: T) => void, destroyable?: any): void;
It registers the given callback as a native listener. The difference with registerChangeListener()
is that csObservable
with native listeners only will not trigger digest cycle update for the document.
registerNativeChangeListenerAndFire(listener: (value: T) => void, destroyable?: any): void;
It registers the given callback as a native listener and sends notification immediately.
unregisterChangeListener(listener: (value: T) => void): void;
It unregisters a registered listener.
unregisterNativeChangeListener(listener: (value: T) => void): void;
It unregisters a registered native listener.