SlideShare a Scribd company logo
1 of 45
Handling Undo-Redo
in Sencha Applications
Nickolay Platonov
@Bryntum
About me
• Nickolay Platonov
- Senior ExtJS developer at Bryntum
- Using ExtJS since version 2.0
- SamuraiJack1 on the forums
- Creator of Joose 3 class system for JavaScript, http://joose.it
- Co-creator of Siesta and Robo tools
- nickolay@bryntum.com
2
Undo/Redo in general
Undo/Redo as a feature
• Very useful
• Standard feature for any serious desktop application
4
Undo/Redo as a feature
• Very useful
• Standard feature for any serious desktop application
• Rarely seen in Sencha applications
• Probably since it is considered too complex to implement
5
Undo/Redo as a feature
• Very useful
• Standard feature for any serious desktop application
• Rarely seen in Sencha applications
• Probably since it is considered too complex to implement
• But doable, as you will see by the end of this talk
6
Undo/Redo –
formal task definition
• It’s all about the application state
• State is presented with data
structures
// Data structure for shape
var shape = {
shapeType : ‘circle’,
x : 100,
y : 100,
radius : 50
}
Undo/Redo –
formal task definition
• It’s all about the application state
• State is presented with data
structures
• For example, for simple graphical
editor a state would be – an array of
shapes.
// Data structure for shape
var shape = {
shapeType : ‘circle’,
x : 100,
y : 100,
radius : 50
}
// Graphical editor state
var appState = [ shape1, shape2, shape3 ]
Undo/Redo –
formal task definition
• Every user action switches
(advances) the application to a new
state
• User moves a circle
• User adds a shape
{ {
shapeType : ‘circle’, shapeType : ‘circle’,
x : 100, x : 200,
y : 100, y : 200,
radius : 50 radius : 50
} }
[ shape1, shape 2 ] [ shape1, shape2, shape3 ]
Undo/Redo – formal task definition
• State change is normally a one-way flow
10
state1 state2 state3
Undo/Redo – formal task definition
• We want to make the flow bidirectional
11
state1 state2 state3
Approach 1 (naive) – Save full snapshot
• Serialize full snapshot of application state
• Deserialize the snapshot and place it as a new application state
12
state1 state2 state3
Approach 1 (naive) – Save full snapshot
• Serialize full snapshot of application state
• Deserialize the snapshot and place it as a new application state
• Pros
- Very simple implementation
• Cons
- Performance (full scan of the dataset)
- Memory consumption (every checkpoint contains all the data)
13
state1 state2 state3
Approach 2 – Save the diff between the states
• Calculate the diff between the application states
• Apply the diff to initial state, to get the new state
14
state1 state2 state3
diff_1 diff_2
Approach 2 – Save the diff between the states
• Calculate the diff between the application states
• Apply the diff to initial state, to get the new state
• Pros
- Memory consumption (only the actually changed data is gathered)
• Cons
- Complexity of diff operation
- Performance of diff operation (both for gathering diffs and applying diffs)
15
state1 state2 state3
diff_1 diff_2
Approach 3 – Save the changelog between the states
• Every diff between the states is a list of actions
• Actions are small, atomic and reversible
16
state1 state2 state3Action1 Action2 Action3 Action4
Approach 3 – Save the changelog between the states
• Every diff between the states is a list of actions
• Actions are small, atomic and reversible
• Pros
- Performance & memory consumption (only the actually changed data is gathered/stored)
- Relatively simple implementation
• Cons
- Application needs to be aware about the undo/redo feature
17
state1 state2 state3Action1 Action2 Action3 Action4
Architecture requirements
• App should follow the MVC pattern
• No state to be kept in the views or controllers (or at least as less as possible)
18
Controller
Model
View
Robo
Robo
• Undo/redo functionality framework, developed by Bryntum
• Targets Sencha applications
• Robo supports ExtJS 5.1.2 / 6.0.1 / 6.0.2 / 6.2.0
• Out of the box, operates on ExtJS data stores (Ext.data.Store and
Ext.data.TreeStore)
• Can be customized to a specific application needs
20
Design & terminology
• The transition between application states is called “transaction”
• Every transaction may contain several smaller “actions”, which are all atomic
• Listens to events from stores, and creates actions from them
21
Robo.Transaction
state1 state2Robo.Action 1 Robo.Action 2
22
http://www.bryntum.com/examples/robo-latest/examples/basic/
Transaction boundaries
• The application may define complex processing rules for data
• Robo is not aware of them
• Developer can choose between the 2 strategies for defining the state checkpoints:
- Timeout (default) – finish the transaction after some time
- Manual – finish every transaction manually (it will start automatically on any change in any
store)
23
Action example
• Robo.action.flat.Add
• Every action has “undo” and
“redo” methods
Ext.define('Robo.action.flat.Add', {
extend : 'Robo.action.Base',
store : null,
records : null,
index : null,
undo : function () {
this.store.remove(this.records);
},
redo : function () {
this.store.insert(this.index, this.records);
}
});
Action example
• Robo.action.flat.Remove
• Every action has “undo” and
“redo” methods
Ext.define('Robo.action.flat.Remove', {
extend : 'Robo.action.Base',
store : null,
records : null,
index : null,
undo : function () {
var me = this;
me.store.insert(me.index, me.records);
},
redo : function () {
var me = this;
me.store.remove(me.records);
}
});
Integration with
Sencha application
• Add Robo.data.Model mixing to
the models
Ext.define('Example.model.Employee', {
extend : 'Ext.data.Model',
modelName : 'Employee',
mixins : { robo : 'Robo.data.Model' },
...
})
Integration with
Sencha application
• Add Robo.data.Model mixing to
the models
• Create an instance of Robo.Manager
Ext.define('Example.model.Employee', {
extend : 'Ext.data.Model',
modelName : 'Employee',
mixins : { robo : 'Robo.data.Model' },
...
})
var robo = new Robo.Manager({
stores : [ 'store1', 'store2', 'store3‘ ]
});
Integration with
Sencha application
• Add Robo.data.Model mixing to
the models
• Create an instance of Robo.Manager
• Add stores to it
Ext.define('Example.model.Employee', {
extend : 'Ext.data.Model',
modelName : 'Employee',
mixins : { robo : 'Robo.data.Model' },
...
})
var robo = new Robo.Manager({
stores : [ 'store1', 'store2', 'store3‘ ]
});
// or add the stores after instantiation
robo.addStore(store1)
robo.addStore(store2)
Integration with
Sencha application
• Add Robo.data.Model mixing to
the models
• Create an instance of Robo.Manager
• Add stores to it
• Start monitoring data changes
Ext.define('Example.model.Employee', {
extend : 'Ext.data.Model',
modelName : 'Employee',
mixins : { robo : 'Robo.data.Model' },
...
})
var robo = new Robo.Manager({
stores : [ 'store1', 'store2', 'store3‘ ]
});
// or add the stores after instantiation
robo.addStore(store1)
robo.addStore(store2)
// start monitoring (after data load)
robo.start();
Integration with
Sencha application
• Add Robo.data.Model mixing to
the models
• Create an instance of Robo.Manager
• Add stores to it
• Start monitoring data changes
• Use the robo.undo()
robo.redo() API calls
Ext.define('Example.model.Employee', {
extend : 'Ext.data.Model',
modelName : 'Employee',
mixins : { robo : 'Robo.data.Model' },
...
})
var robo = new Robo.Manager({
stores : [ 'store1', 'store2', 'store3‘ ]
});
// or add the stores after instantiation
robo.addStore(store1)
robo.addStore(store2)
// start monitoring (after data load)
robo.start();
// at some point later
robo.undo()
robo.redo()
Dependent data
• Data objects often depends on each
other
• Change in one object triggers a
change in another (possibly in
another store)
// user action
USER: employee1.set(‘hourlyRate’, 100)
// application triggers (activated by ‘update’ event)
APP: employee1.set(‘monthlySalary’, 16000)
APP: employee1.set(‘yearlySalary’, 192000)
Dependent data
• Data objects often depends on each
other
• Change in one object triggers a
change in another (possibly in
another store)
• Robo performs the undo/redo using
the standard data package API (will
trigger standard events)
• App may react on every data
change triggered by Robo
// user action
USER: employee1.set(‘hourlyRate’, 100)
// application triggers (activated by ‘update’ event)
APP: employee1.set(‘monthlySalary’, 16000)
APP: employee1.set(‘yearlySalary’, 192000)
// robo.undo()
ROBO: employee1.set(‘yearlySalary’, 96000)
APP: employee1.set(‘hourlyRate’, 50)
APP: employee1.set(‘monthlySalary’, 8000)
ROBO: employee1.set(‘monthlySalary’, 8000)
APP: employee1.set(‘hourlyRate’, 50)
APP: employee1.set(‘yearlySalary’, 96000)
ROBO: employee1.set(‘hourlyRate’, 50)
APP: employee1.set(‘monthlySalary’, 8000)
APP: employee1.set(‘yearlySalary’, 96000)
Solution
• Application needs to be aware about current data flow “mode” –
“normal/undo/redo”
• Skip the data propagation rules in “undo/redo” mode
33
Technically
• Add the Robo.data.Store mixin
to the store
• Use the isUndoingOrRedoing()
method to check if current flow is
undo/redo
Ext.define('Example.store.EmployeeList', {
extend : 'Ext.data.Store',
mixins : { robo : 'Robo.data.Store' },
onRecordUpdate : function (...) {
if (!this.isUndoingOrRedoing()) {
...
}
}
});
Suspended events
• Robo can’t record anything, if events on a store are suspended
• Moreover, a missed action leads to inconsistent undo/redo queue state
• Application should not change store data if events are suspended (or, suspend
events with the queuing option)
• Or, create missing actions manually
roboManager.currentTransaction.addAction()
35
Robo widgets. Transaction titles
• Robo provides two simple buttons – undo and redo
• Every button contains a menu with an item for every transaction to undo/redo
• Developer can define a title for the transaction by implementing the “getTitle()”
method on the models
36
Advanced Robo showcase
Bryntum Ext Gantt
• 5 stores, one of them is a TreeStore
• Very complex processing rules
(change in one store propagates to
others)
me.undoManager = new Gnt.data.undoredo.Manager({
stores : [
calendarManager,
taskStore,
resourceStore,
assignmentStore,
dependencyStore
]
});
Bryntum Ext Gantt
• 5 stores, one of them is a TreeStore
• Very complex processing rules
(change in one store propagates to
others)
• Works like a charm
me.undoManager = new Gnt.data.undoredo.Manager({
stores : [
calendarManager,
taskStore,
resourceStore,
assignmentStore,
dependencyStore
]
});
Bryntum Ext Gantt
• 5 stores, one of them is a TreeStore
• Very complex processing rules
(change in one store propagates to
others)
• Works like a charm
• Required some customization
me.undoManager = new Gnt.data.undoredo.Manager({
stores : [
calendarManager,
taskStore,
resourceStore,
assignmentStore,
dependencyStore
]
});
41
http://www.bryntum.com/examples/gantt-latest/examples/advanced/advanced.html#en
Conclusion
• With Robo, the undo-redo functionality is easy to add to any Sencha application,
following a few simple rules during development
• There are already several successful implementations
42
Conclusion
• With Robo, the undo-redo functionality is easy to add to any Sencha application,
following a few simple rules during development
• There are already several successful implementations
• Next time you hear the request for undo/redo – don’t reject it immediately.
43
Learn more
• http://www.bryntum.com/products/robo/
• http://www.bryntum.com/docs/robo/#!/guide/robo_getting_started
• Any questions?
44
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov

More Related Content

What's hot

SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...Sencha
 
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...Sencha
 
Integrating AngularJS with Drupal 7
Integrating AngularJS with Drupal 7Integrating AngularJS with Drupal 7
Integrating AngularJS with Drupal 7andrewmriley
 
Here Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressHere Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressRami Sayar
 
An Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemAn Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemRami Sayar
 
Puppet Camp Portland: Nagios Management With Puppet (Beginner)
Puppet Camp Portland: Nagios Management With Puppet (Beginner)Puppet Camp Portland: Nagios Management With Puppet (Beginner)
Puppet Camp Portland: Nagios Management With Puppet (Beginner)Puppet
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with MavenKhan625
 
User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012
User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012
User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012Atlassian
 
High Performance Drupal
High Performance DrupalHigh Performance Drupal
High Performance DrupalJeff Geerling
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-IIIprinceirfancivil
 
Ansible for large scale deployment
Ansible for large scale deploymentAnsible for large scale deployment
Ansible for large scale deploymentKarthik .P.R
 
MuleSoft ESB Payload Encrypt using Anypoint Security
MuleSoft ESB Payload Encrypt using Anypoint SecurityMuleSoft ESB Payload Encrypt using Anypoint Security
MuleSoft ESB Payload Encrypt using Anypoint Securityakashdprajapati
 
Introdcution to Adobe CQ
Introdcution to Adobe CQIntrodcution to Adobe CQ
Introdcution to Adobe CQRest West
 
The Many Ways to Test Your React App
The Many Ways to Test Your React AppThe Many Ways to Test Your React App
The Many Ways to Test Your React AppAll Things Open
 
MuleSoft ESB Filtering data instead of Looping
MuleSoft ESB Filtering data instead of LoopingMuleSoft ESB Filtering data instead of Looping
MuleSoft ESB Filtering data instead of Loopingakashdprajapati
 
Advanced moduledevelopment d6_slideshare
Advanced moduledevelopment d6_slideshareAdvanced moduledevelopment d6_slideshare
Advanced moduledevelopment d6_slideshareOpevel
 
Best Practices for WordPress
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPressTaylor Lovett
 

What's hot (20)

SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
 
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
 
Integrating AngularJS with Drupal 7
Integrating AngularJS with Drupal 7Integrating AngularJS with Drupal 7
Integrating AngularJS with Drupal 7
 
Here Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressHere Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPress
 
An Intense Overview of the React Ecosystem
An Intense Overview of the React EcosystemAn Intense Overview of the React Ecosystem
An Intense Overview of the React Ecosystem
 
Puppet Camp Portland: Nagios Management With Puppet (Beginner)
Puppet Camp Portland: Nagios Management With Puppet (Beginner)Puppet Camp Portland: Nagios Management With Puppet (Beginner)
Puppet Camp Portland: Nagios Management With Puppet (Beginner)
 
Extending ansible
Extending ansibleExtending ansible
Extending ansible
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with Maven
 
User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012
User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012
User Macros: Making Your Own Improvements to Confluence - Atlassian Summit 2012
 
High Performance Drupal
High Performance DrupalHigh Performance Drupal
High Performance Drupal
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-III
 
Ansible for large scale deployment
Ansible for large scale deploymentAnsible for large scale deployment
Ansible for large scale deployment
 
MuleSoft ESB Payload Encrypt using Anypoint Security
MuleSoft ESB Payload Encrypt using Anypoint SecurityMuleSoft ESB Payload Encrypt using Anypoint Security
MuleSoft ESB Payload Encrypt using Anypoint Security
 
Maven
Maven Maven
Maven
 
Introdcution to Adobe CQ
Introdcution to Adobe CQIntrodcution to Adobe CQ
Introdcution to Adobe CQ
 
The Many Ways to Test Your React App
The Many Ways to Test Your React AppThe Many Ways to Test Your React App
The Many Ways to Test Your React App
 
MuleSoft ESB Filtering data instead of Looping
MuleSoft ESB Filtering data instead of LoopingMuleSoft ESB Filtering data instead of Looping
MuleSoft ESB Filtering data instead of Looping
 
Introduction to CQ5
Introduction to CQ5Introduction to CQ5
Introduction to CQ5
 
Advanced moduledevelopment d6_slideshare
Advanced moduledevelopment d6_slideshareAdvanced moduledevelopment d6_slideshare
Advanced moduledevelopment d6_slideshare
 
Best Practices for WordPress
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPress
 

Viewers also liked

SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...Sencha
 
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil ManvarSenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil ManvarSencha
 
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...Sencha
 
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...Sencha
 
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory HardySenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory HardySencha
 
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...Sencha
 
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSencha
 
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...Sencha
 
Ext JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell SimeonsExt JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell SimeonsSencha
 
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...Sencha
 
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark BrocatoSenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark BrocatoSencha
 
Building Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff StanoBuilding Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff StanoSencha
 
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...Sencha
 
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...Sencha
 
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...Sencha
 
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling Sencha
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSencha
 
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant   SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant Sencha
 
SenchaCon 2016: Oracle Forms Modernisation - Owen Pagan
SenchaCon 2016: Oracle Forms Modernisation - Owen PaganSenchaCon 2016: Oracle Forms Modernisation - Owen Pagan
SenchaCon 2016: Oracle Forms Modernisation - Owen PaganSencha
 
Maths assignment
Maths assignmentMaths assignment
Maths assignmentNtshima
 

Viewers also liked (20)

SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
 
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil ManvarSenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
 
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
 
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
 
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory HardySenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
 
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
 
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
 
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
 
Ext JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell SimeonsExt JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell Simeons
 
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
 
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark BrocatoSenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
 
Building Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff StanoBuilding Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff Stano
 
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
 
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
 
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
 
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
 
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant   SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
 
SenchaCon 2016: Oracle Forms Modernisation - Owen Pagan
SenchaCon 2016: Oracle Forms Modernisation - Owen PaganSenchaCon 2016: Oracle Forms Modernisation - Owen Pagan
SenchaCon 2016: Oracle Forms Modernisation - Owen Pagan
 
Maths assignment
Maths assignmentMaths assignment
Maths assignment
 

Similar to SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov

React state management with Redux and MobX
React state management with Redux and MobXReact state management with Redux and MobX
React state management with Redux and MobXDarko Kukovec
 
Predictable reactive state management - ngrx
Predictable reactive state management - ngrxPredictable reactive state management - ngrx
Predictable reactive state management - ngrxIlia Idakiev
 
Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts weili_at_slideshare
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profilerIhor Bobak
 
Insight on MongoDB Change Stream - Abhishek.D, Mydbops Team
Insight on MongoDB Change Stream - Abhishek.D, Mydbops TeamInsight on MongoDB Change Stream - Abhishek.D, Mydbops Team
Insight on MongoDB Change Stream - Abhishek.D, Mydbops TeamMydbops
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Gabor Varadi
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of SignalsCoding Academy
 
Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)Fabio Tiriticco
 
Using Automatic Refactoring to Improve Energy Efficiency of Android Apps
Using Automatic Refactoring to Improve Energy Efficiency of Android AppsUsing Automatic Refactoring to Improve Energy Efficiency of Android Apps
Using Automatic Refactoring to Improve Energy Efficiency of Android AppsLuis Cruz
 
Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Sandro Mancuso
 
Developing Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's GuideDeveloping Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's GuideMohanraj Thirumoorthy
 
Variables Arguments and control flow_UiPath.ppt
Variables Arguments and control flow_UiPath.pptVariables Arguments and control flow_UiPath.ppt
Variables Arguments and control flow_UiPath.pptRohit Radhakrishnan
 
downloads_introduction to redux.pptx
downloads_introduction to redux.pptxdownloads_introduction to redux.pptx
downloads_introduction to redux.pptxNavneetKumar111924
 
Reactive programming with rx java
Reactive programming with rx javaReactive programming with rx java
Reactive programming with rx javaCongTrung Vnit
 
Developing maintainable Cordova applications
Developing maintainable Cordova applicationsDeveloping maintainable Cordova applications
Developing maintainable Cordova applicationsIvano Malavolta
 
Model-based programming and AI-assisted software development
Model-based programming and AI-assisted software developmentModel-based programming and AI-assisted software development
Model-based programming and AI-assisted software developmentEficode
 
MVP Community Camp 2014 - How to use enhanced features of Windows 8.1 Store ...
MVP Community Camp 2014 - How to useenhanced features of Windows 8.1 Store ...MVP Community Camp 2014 - How to useenhanced features of Windows 8.1 Store ...
MVP Community Camp 2014 - How to use enhanced features of Windows 8.1 Store ...Akira Hatsune
 
Cloudify workshop at CCCEU 2014
Cloudify workshop at CCCEU 2014 Cloudify workshop at CCCEU 2014
Cloudify workshop at CCCEU 2014 Uri Cohen
 

Similar to SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov (20)

React state management with Redux and MobX
React state management with Redux and MobXReact state management with Redux and MobX
React state management with Redux and MobX
 
Predictable reactive state management - ngrx
Predictable reactive state management - ngrxPredictable reactive state management - ngrx
Predictable reactive state management - ngrx
 
Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profiler
 
01 oracle architecture
01 oracle architecture01 oracle architecture
01 oracle architecture
 
Insight on MongoDB Change Stream - Abhishek.D, Mydbops Team
Insight on MongoDB Change Stream - Abhishek.D, Mydbops TeamInsight on MongoDB Change Stream - Abhishek.D, Mydbops Team
Insight on MongoDB Change Stream - Abhishek.D, Mydbops Team
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
 
Angular 16 – the rise of Signals
Angular 16 – the rise of SignalsAngular 16 – the rise of Signals
Angular 16 – the rise of Signals
 
Redux
ReduxRedux
Redux
 
Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)Reactive Programming or Reactive Systems? (spoiler: both)
Reactive Programming or Reactive Systems? (spoiler: both)
 
Using Automatic Refactoring to Improve Energy Efficiency of Android Apps
Using Automatic Refactoring to Improve Energy Efficiency of Android AppsUsing Automatic Refactoring to Improve Energy Efficiency of Android Apps
Using Automatic Refactoring to Improve Energy Efficiency of Android Apps
 
Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014
 
Developing Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's GuideDeveloping Microservices using Spring - Beginner's Guide
Developing Microservices using Spring - Beginner's Guide
 
Variables Arguments and control flow_UiPath.ppt
Variables Arguments and control flow_UiPath.pptVariables Arguments and control flow_UiPath.ppt
Variables Arguments and control flow_UiPath.ppt
 
downloads_introduction to redux.pptx
downloads_introduction to redux.pptxdownloads_introduction to redux.pptx
downloads_introduction to redux.pptx
 
Reactive programming with rx java
Reactive programming with rx javaReactive programming with rx java
Reactive programming with rx java
 
Developing maintainable Cordova applications
Developing maintainable Cordova applicationsDeveloping maintainable Cordova applications
Developing maintainable Cordova applications
 
Model-based programming and AI-assisted software development
Model-based programming and AI-assisted software developmentModel-based programming and AI-assisted software development
Model-based programming and AI-assisted software development
 
MVP Community Camp 2014 - How to use enhanced features of Windows 8.1 Store ...
MVP Community Camp 2014 - How to useenhanced features of Windows 8.1 Store ...MVP Community Camp 2014 - How to useenhanced features of Windows 8.1 Store ...
MVP Community Camp 2014 - How to use enhanced features of Windows 8.1 Store ...
 
Cloudify workshop at CCCEU 2014
Cloudify workshop at CCCEU 2014 Cloudify workshop at CCCEU 2014
Cloudify workshop at CCCEU 2014
 

More from Sencha

Breathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web ComponentsBreathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web ComponentsSencha
 
Ext JS 6.6 Highlights
Ext JS 6.6 HighlightsExt JS 6.6 Highlights
Ext JS 6.6 HighlightsSencha
 
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...Sencha
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha
 
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App TestingSencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App TestingSencha
 
Sencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha TestSencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha TestSencha
 
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...Sencha
 
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha
 
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App Sencha
 
Sencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop FirstSencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop FirstSencha
 
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and BeyondSencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and BeyondSencha
 
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data GridLeveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data GridSencha
 
Learn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research ReportLearn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research ReportSencha
 
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React AppsIntroducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React AppsSencha
 

More from Sencha (14)

Breathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web ComponentsBreathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web Components
 
Ext JS 6.6 Highlights
Ext JS 6.6 HighlightsExt JS 6.6 Highlights
Ext JS 6.6 Highlights
 
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
 
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App TestingSencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
 
Sencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha TestSencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha Test
 
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
 
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
 
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
 
Sencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop FirstSencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop First
 
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and BeyondSencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
 
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data GridLeveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
 
Learn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research ReportLearn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research Report
 
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React AppsIntroducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
 

Recently uploaded

Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 

Recently uploaded (20)

Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 

SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov

  • 1. Handling Undo-Redo in Sencha Applications Nickolay Platonov @Bryntum
  • 2. About me • Nickolay Platonov - Senior ExtJS developer at Bryntum - Using ExtJS since version 2.0 - SamuraiJack1 on the forums - Creator of Joose 3 class system for JavaScript, http://joose.it - Co-creator of Siesta and Robo tools - nickolay@bryntum.com 2
  • 4. Undo/Redo as a feature • Very useful • Standard feature for any serious desktop application 4
  • 5. Undo/Redo as a feature • Very useful • Standard feature for any serious desktop application • Rarely seen in Sencha applications • Probably since it is considered too complex to implement 5
  • 6. Undo/Redo as a feature • Very useful • Standard feature for any serious desktop application • Rarely seen in Sencha applications • Probably since it is considered too complex to implement • But doable, as you will see by the end of this talk 6
  • 7. Undo/Redo – formal task definition • It’s all about the application state • State is presented with data structures // Data structure for shape var shape = { shapeType : ‘circle’, x : 100, y : 100, radius : 50 }
  • 8. Undo/Redo – formal task definition • It’s all about the application state • State is presented with data structures • For example, for simple graphical editor a state would be – an array of shapes. // Data structure for shape var shape = { shapeType : ‘circle’, x : 100, y : 100, radius : 50 } // Graphical editor state var appState = [ shape1, shape2, shape3 ]
  • 9. Undo/Redo – formal task definition • Every user action switches (advances) the application to a new state • User moves a circle • User adds a shape { { shapeType : ‘circle’, shapeType : ‘circle’, x : 100, x : 200, y : 100, y : 200, radius : 50 radius : 50 } } [ shape1, shape 2 ] [ shape1, shape2, shape3 ]
  • 10. Undo/Redo – formal task definition • State change is normally a one-way flow 10 state1 state2 state3
  • 11. Undo/Redo – formal task definition • We want to make the flow bidirectional 11 state1 state2 state3
  • 12. Approach 1 (naive) – Save full snapshot • Serialize full snapshot of application state • Deserialize the snapshot and place it as a new application state 12 state1 state2 state3
  • 13. Approach 1 (naive) – Save full snapshot • Serialize full snapshot of application state • Deserialize the snapshot and place it as a new application state • Pros - Very simple implementation • Cons - Performance (full scan of the dataset) - Memory consumption (every checkpoint contains all the data) 13 state1 state2 state3
  • 14. Approach 2 – Save the diff between the states • Calculate the diff between the application states • Apply the diff to initial state, to get the new state 14 state1 state2 state3 diff_1 diff_2
  • 15. Approach 2 – Save the diff between the states • Calculate the diff between the application states • Apply the diff to initial state, to get the new state • Pros - Memory consumption (only the actually changed data is gathered) • Cons - Complexity of diff operation - Performance of diff operation (both for gathering diffs and applying diffs) 15 state1 state2 state3 diff_1 diff_2
  • 16. Approach 3 – Save the changelog between the states • Every diff between the states is a list of actions • Actions are small, atomic and reversible 16 state1 state2 state3Action1 Action2 Action3 Action4
  • 17. Approach 3 – Save the changelog between the states • Every diff between the states is a list of actions • Actions are small, atomic and reversible • Pros - Performance & memory consumption (only the actually changed data is gathered/stored) - Relatively simple implementation • Cons - Application needs to be aware about the undo/redo feature 17 state1 state2 state3Action1 Action2 Action3 Action4
  • 18. Architecture requirements • App should follow the MVC pattern • No state to be kept in the views or controllers (or at least as less as possible) 18 Controller Model View
  • 19. Robo
  • 20. Robo • Undo/redo functionality framework, developed by Bryntum • Targets Sencha applications • Robo supports ExtJS 5.1.2 / 6.0.1 / 6.0.2 / 6.2.0 • Out of the box, operates on ExtJS data stores (Ext.data.Store and Ext.data.TreeStore) • Can be customized to a specific application needs 20
  • 21. Design & terminology • The transition between application states is called “transaction” • Every transaction may contain several smaller “actions”, which are all atomic • Listens to events from stores, and creates actions from them 21 Robo.Transaction state1 state2Robo.Action 1 Robo.Action 2
  • 23. Transaction boundaries • The application may define complex processing rules for data • Robo is not aware of them • Developer can choose between the 2 strategies for defining the state checkpoints: - Timeout (default) – finish the transaction after some time - Manual – finish every transaction manually (it will start automatically on any change in any store) 23
  • 24. Action example • Robo.action.flat.Add • Every action has “undo” and “redo” methods Ext.define('Robo.action.flat.Add', { extend : 'Robo.action.Base', store : null, records : null, index : null, undo : function () { this.store.remove(this.records); }, redo : function () { this.store.insert(this.index, this.records); } });
  • 25. Action example • Robo.action.flat.Remove • Every action has “undo” and “redo” methods Ext.define('Robo.action.flat.Remove', { extend : 'Robo.action.Base', store : null, records : null, index : null, undo : function () { var me = this; me.store.insert(me.index, me.records); }, redo : function () { var me = this; me.store.remove(me.records); } });
  • 26. Integration with Sencha application • Add Robo.data.Model mixing to the models Ext.define('Example.model.Employee', { extend : 'Ext.data.Model', modelName : 'Employee', mixins : { robo : 'Robo.data.Model' }, ... })
  • 27. Integration with Sencha application • Add Robo.data.Model mixing to the models • Create an instance of Robo.Manager Ext.define('Example.model.Employee', { extend : 'Ext.data.Model', modelName : 'Employee', mixins : { robo : 'Robo.data.Model' }, ... }) var robo = new Robo.Manager({ stores : [ 'store1', 'store2', 'store3‘ ] });
  • 28. Integration with Sencha application • Add Robo.data.Model mixing to the models • Create an instance of Robo.Manager • Add stores to it Ext.define('Example.model.Employee', { extend : 'Ext.data.Model', modelName : 'Employee', mixins : { robo : 'Robo.data.Model' }, ... }) var robo = new Robo.Manager({ stores : [ 'store1', 'store2', 'store3‘ ] }); // or add the stores after instantiation robo.addStore(store1) robo.addStore(store2)
  • 29. Integration with Sencha application • Add Robo.data.Model mixing to the models • Create an instance of Robo.Manager • Add stores to it • Start monitoring data changes Ext.define('Example.model.Employee', { extend : 'Ext.data.Model', modelName : 'Employee', mixins : { robo : 'Robo.data.Model' }, ... }) var robo = new Robo.Manager({ stores : [ 'store1', 'store2', 'store3‘ ] }); // or add the stores after instantiation robo.addStore(store1) robo.addStore(store2) // start monitoring (after data load) robo.start();
  • 30. Integration with Sencha application • Add Robo.data.Model mixing to the models • Create an instance of Robo.Manager • Add stores to it • Start monitoring data changes • Use the robo.undo() robo.redo() API calls Ext.define('Example.model.Employee', { extend : 'Ext.data.Model', modelName : 'Employee', mixins : { robo : 'Robo.data.Model' }, ... }) var robo = new Robo.Manager({ stores : [ 'store1', 'store2', 'store3‘ ] }); // or add the stores after instantiation robo.addStore(store1) robo.addStore(store2) // start monitoring (after data load) robo.start(); // at some point later robo.undo() robo.redo()
  • 31. Dependent data • Data objects often depends on each other • Change in one object triggers a change in another (possibly in another store) // user action USER: employee1.set(‘hourlyRate’, 100) // application triggers (activated by ‘update’ event) APP: employee1.set(‘monthlySalary’, 16000) APP: employee1.set(‘yearlySalary’, 192000)
  • 32. Dependent data • Data objects often depends on each other • Change in one object triggers a change in another (possibly in another store) • Robo performs the undo/redo using the standard data package API (will trigger standard events) • App may react on every data change triggered by Robo // user action USER: employee1.set(‘hourlyRate’, 100) // application triggers (activated by ‘update’ event) APP: employee1.set(‘monthlySalary’, 16000) APP: employee1.set(‘yearlySalary’, 192000) // robo.undo() ROBO: employee1.set(‘yearlySalary’, 96000) APP: employee1.set(‘hourlyRate’, 50) APP: employee1.set(‘monthlySalary’, 8000) ROBO: employee1.set(‘monthlySalary’, 8000) APP: employee1.set(‘hourlyRate’, 50) APP: employee1.set(‘yearlySalary’, 96000) ROBO: employee1.set(‘hourlyRate’, 50) APP: employee1.set(‘monthlySalary’, 8000) APP: employee1.set(‘yearlySalary’, 96000)
  • 33. Solution • Application needs to be aware about current data flow “mode” – “normal/undo/redo” • Skip the data propagation rules in “undo/redo” mode 33
  • 34. Technically • Add the Robo.data.Store mixin to the store • Use the isUndoingOrRedoing() method to check if current flow is undo/redo Ext.define('Example.store.EmployeeList', { extend : 'Ext.data.Store', mixins : { robo : 'Robo.data.Store' }, onRecordUpdate : function (...) { if (!this.isUndoingOrRedoing()) { ... } } });
  • 35. Suspended events • Robo can’t record anything, if events on a store are suspended • Moreover, a missed action leads to inconsistent undo/redo queue state • Application should not change store data if events are suspended (or, suspend events with the queuing option) • Or, create missing actions manually roboManager.currentTransaction.addAction() 35
  • 36. Robo widgets. Transaction titles • Robo provides two simple buttons – undo and redo • Every button contains a menu with an item for every transaction to undo/redo • Developer can define a title for the transaction by implementing the “getTitle()” method on the models 36
  • 38. Bryntum Ext Gantt • 5 stores, one of them is a TreeStore • Very complex processing rules (change in one store propagates to others) me.undoManager = new Gnt.data.undoredo.Manager({ stores : [ calendarManager, taskStore, resourceStore, assignmentStore, dependencyStore ] });
  • 39. Bryntum Ext Gantt • 5 stores, one of them is a TreeStore • Very complex processing rules (change in one store propagates to others) • Works like a charm me.undoManager = new Gnt.data.undoredo.Manager({ stores : [ calendarManager, taskStore, resourceStore, assignmentStore, dependencyStore ] });
  • 40. Bryntum Ext Gantt • 5 stores, one of them is a TreeStore • Very complex processing rules (change in one store propagates to others) • Works like a charm • Required some customization me.undoManager = new Gnt.data.undoredo.Manager({ stores : [ calendarManager, taskStore, resourceStore, assignmentStore, dependencyStore ] });
  • 42. Conclusion • With Robo, the undo-redo functionality is easy to add to any Sencha application, following a few simple rules during development • There are already several successful implementations 42
  • 43. Conclusion • With Robo, the undo-redo functionality is easy to add to any Sencha application, following a few simple rules during development • There are already several successful implementations • Next time you hear the request for undo/redo – don’t reject it immediately. 43
  • 44. Learn more • http://www.bryntum.com/products/robo/ • http://www.bryntum.com/docs/robo/#!/guide/robo_getting_started • Any questions? 44