Skip to content

Commit d72c3fd

Browse files
committed
[ADD] developer: effect service
closes odoo#1210 Signed-off-by: Simon Genin (ges@odoo) <[email protected]>
1 parent 1e6c12b commit d72c3fd

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
lines changed
Loading
Loading

content/developer/reference/frontend/registries.rst

+2
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,5 @@ Example:
244244
};
245245
}
246246
247+
:ref:`Effect registry<javascript/effect_registry>`
248+
--------------------------------------------------

content/developer/reference/frontend/services.rst

+176
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ Reference List
118118
- Short Description
119119
* - :ref:`cookie <services/cookie>`
120120
- read or modify cookies
121+
* - :ref:`effect <services/effect>`
122+
- display graphical effects
121123
* - :ref:`notification <services/notification>`
122124
- display notifications
123125
* - :ref:`rpc <services/rpc>`
@@ -165,6 +167,180 @@ API
165167

166168
Deletes the cookie `name`.
167169

170+
.. _services/effect:
171+
172+
Effect service
173+
--------------
174+
175+
Overview
176+
~~~~~~~~
177+
178+
* Technical name: `effect`
179+
* Dependencies: None
180+
181+
Effects are graphical elements that can be temporarily displayed on top of the page, usually to provide feedback to the user that something interesting happened.
182+
183+
A good example would be the rainbow man:
184+
185+
.. image:: images/rainbow_man.png
186+
:alt: The rainbow man effect
187+
:width: 600
188+
:align: center
189+
190+
191+
Here's how this can be displayed:
192+
193+
.. code-block:: javascript
194+
195+
const effectService = useService("effect");
196+
effectService.add({
197+
type: "rainbow_man",
198+
message: "Boom! Team record for the past 30 days.",
199+
});
200+
201+
.. warning ::
202+
The hook `useEffect` is not related to the effect service.
203+
204+
API
205+
~~~
206+
207+
.. js:function:: effectService.add(options)
208+
209+
:param object options: the options for the effect. They will get passed along to the underlying effect component.
210+
211+
Display an effect.
212+
213+
The options are defined by:
214+
215+
.. code-block:: ts
216+
217+
@typedef {Object} [EffectOptions]
218+
@property {string} [type="rainbow_man"]
219+
// The name of the desired effect
220+
221+
Available effects
222+
~~~~~~~~~~~~~~~~~
223+
224+
Currently, the only effect is the rainbow man.
225+
226+
RainbowMan
227+
**********
228+
229+
.. code-block:: javascript
230+
231+
effectService.add({ type: "rainbow_man" });
232+
233+
.. list-table::
234+
:widths: 20 40 40
235+
:header-rows: 1
236+
237+
* - Name
238+
- Type
239+
- Description
240+
* - `params.message`
241+
- `string?="Well Done"`
242+
- The message in the notice the rainbowman holds or the content of the notification if effects are disabled.
243+
244+
Can be a simple a string.
245+
246+
Can be a string representation of html (prefer component if you want interactions in the DOM).
247+
* - `params.img_url`
248+
- `string?=/web/static/img/smile.svg`
249+
- The url of the image to display inside the rainbow.
250+
* - `params.messageIsHtml`
251+
- `boolean?=false`
252+
- Set to true if the message encodes html, s.t. it will be correctly inserted into the DOM.
253+
* - `params.fadeout`
254+
- `("slow"|"medium"|"fast"|"no")?="medium"`
255+
- Delay for rainbowman to disappear.
256+
257+
`"fast"` will make rainbowman dissapear quickly.
258+
259+
`"medium"` and 'slow' will wait little longer before disappearing (can be used when `options.message` is longer).
260+
261+
`"no"` will keep rainbowman on screen until user clicks anywhere outside rainbowman.
262+
263+
* - `params.Component`
264+
- `owl.Component?=RainbowMan`
265+
- Component class to instantiate (if effects aren't disabled).
266+
* - `params.props`
267+
- `object?={}`
268+
- If params.Component is given, its props can be passed with this argument.
269+
270+
How to add an effect
271+
~~~~~~~~~~~~~~~~~~~~
272+
273+
.. _javascript/effect_registry:
274+
275+
The effects are stored in a registry called `effects`.
276+
You can add new effects by providing a name and a function.
277+
278+
.. code-block:: javascript
279+
280+
const effectRegistry = registry.category("effects");
281+
effectRegistry.add("rainbow_man", rainbowManEffectFunction);
282+
283+
The function must follow this API:
284+
285+
.. js:function:: <newEffectFunction>(env, params)
286+
287+
:param Env env: the environment received by the service
288+
289+
:param object params: the params received from the add function on the service.
290+
291+
:returns: `({Component, props} | void)` A component and its props or nothing.
292+
293+
This function must create a component and return it. This component is mounted inside the
294+
effect component container.
295+
296+
Example
297+
~~~~~~~
298+
299+
Let's say we want to add an effect that add a sepia look at the page.
300+
301+
.. code-block:: javascript
302+
303+
/** @odoo-module **/
304+
305+
import { registry } from "@web/core/registry";
306+
const { Component, tags } = owl;
307+
308+
class SepiaEffect extends Component {}
309+
SepiaEffect.template = tags.xml`
310+
<div style="
311+
position: absolute;
312+
left: 0;
313+
top: 0;
314+
width: 100%;
315+
height: 100%;
316+
pointer-events: none;
317+
background: rgba(124,87,0, 0.4);
318+
"></div>
319+
`;
320+
321+
export function sepiaEffectProvider(env, params = {}) {
322+
return {
323+
Component: SepiaEffect,
324+
};
325+
}
326+
327+
const effectRegistry = registry.category("effects");
328+
effectRegistry.add("sepia", sepiaEffectProvider);
329+
330+
331+
And then, call it somewhere you want and you will see the result.
332+
Here, it is called in webclient.js to make it visible everywhere for the example.
333+
334+
.. code-block:: javascript
335+
336+
const effectService = useService("effect");
337+
effectService.add({ type: "sepia" });
338+
339+
.. image:: images/odoo_sepia.png
340+
:alt: Odoo in sepia
341+
:width: 600
342+
:align: center
343+
168344
.. _services/notification:
169345

170346
Notification service

0 commit comments

Comments
 (0)