SlideShare ist ein Scribd-Unternehmen logo
1 von 113
Downloaden Sie, um offline zu lesen
AMBITIOUS UX FOR
AMBITIOUS APPS
EMBERCONF 2015
Lauren Elizabeth Tan
@sugarpirate_ @poteto
DESIGN DEV
Lauren Elizabeth Tan
Designer & Front End Developer
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
BUT I’M NOT A DESIGNER
“Most people make the mistake of thinking
design is what it looks like. That’s not what we
think design is. It’s not just what it looks like
and feels like. Design is how it works.”
applyConcatenatedProperties()
giveDescriptorSuper()
beginPropertyChanges()
=
What is good design?
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
REACTIVE?
FLOW OF DATA
&
MAINTAINING RELATIONSHIPS
BETWEEN THAT DATA
var EmberObject =
CoreObject.extend(Observable);
FUNCTIONAL REACTIVE
PROGRAMMING?
FUNCTIONAL REACTIVE
PROGRAMMING?
FUNCTIONAL REACTIVE PROGRAMMING?
Immutability
Some side effects
EVENT STREAMS
Things that consist of discrete events
.asEventStream('click')
https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
PROPERTIES
Things that change and have a current state
(100, 250)
(300, 200)
Array.prototype#map
Array.prototype#filter
Array.prototype#reduce
Array.prototype#concat
BACON.JS
FRP library
!==
(obviously)
Ember.observer
Ember.computed
Ember.Observable
Ember.Evented
Ember.on
THE OBSERVER PATTERN
Computed properties and observers
COMPUTED PROPERTIES
Transforms properties, and keeps relationships in sync
export default Ember.Object.extend({
fullName: computed('firstName', 'lastName', function() {
return `${get(this, 'firstName')} ${get(this, 'lastName')}`;
})
});
COMPUTED PROPERTY MACROS
Keeping things DRY
export default function(separator, dependentKeys) {
let computedFunc = computed(function() {
let values = dependentKeys.map((dependentKey) => {
return getWithDefault(this, dependentKey, '');
});
return values.join(separator);
});
return computedFunc.property.apply(computedFunc, dependentKeys);
};
DEMO
http://emberjs.jsbin.com/vubaga/12/edit?js,output
import joinWith from '...';
export default Ember.Object.extend({
fullName: joinWith(' ', [
'title',
'firstName',
'middleName',
'lastName',
'suffix'
])
});
get(this, 'fullName');
// Mr Harvey Reginald Specter Esq.
Ember.computed.{map,mapBy}
Ember.computed.{filter,filterBy}
Ember.computed.sort
Ember.computed.intersect
Ember.computed.setDiff
Ember.computed.uniq
Ember.computed.readTheAPIDocs
http://emberjs.com/api/#method_computed
OBSERVERS
Synchronously invoked when dependent
properties change
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
ƈhttp://youtu.be/OK34L4-qaDQ
Waterboarding at Guantanamo Bay
sounds super rad if you don't know
what either of those things are.
The person who would proof read
Hitler's speeches was a grammar
Nazi.
If your shirt isn't tucked into your
pants, then your pants are tucked
into your shirt.
ƈ+
/index /usersroute:user
model()
{ this.store.find('user') }
// returns Promise

GET "https://foo.com/v1/api/users"
/loading
/error
resolve()
reject()
Service
ƈ
Reddit API
Index Route User RouteLoading Route
Fetch top posts
Component
Fetch user records resolve()
Get random message
Display shower thought
SERVICE
Ember.Service.extend({ ... });
messages : Ember.A([]),
topPeriods : [ 'day', 'week', 'month', 'year', 'all' ],
topPeriod : 'day',
subreddit : 'showerthoughts',
getPostsBy(subreddit, period) {
let url = `//www.reddit.com/r/${subreddit}/top.json?sort=top&t=${period}`;
return new RSVP.Promise((resolve, reject) => {
getJSON(url)
.then((res) => {
let titles = res.data.children.mapBy('data.title');
resolve(titles);
}).catch(/* ... */);
});
}
_handleTopPeriodChange: observer('subreddit', 'topPeriod', function() {
let subreddit = get(this, 'subreddit');
let topPeriod = get(this, 'topPeriod');
run.once(this, () => {
this.getPostsBy(subreddit, topPeriod)
.then((posts) => {
set(this, 'messages', posts);
});
});
}).on('init'),
COMPONENT
export default Ember.Component.extend({
service : inject.service('shower-thoughts'),
randomMsg : computedSample('service.messages'),
loadingText : 'Loading',
classNames : [ 'loadingMessage' ]
});
export default function(dependentKey) {
return computed(`${dependentKey}.@each`, () => {
let items = getWithDefault(this, dependentKey, Ember.A([]));
let randomItem = items[Math.floor(Math.random() * items.get('length'))];
return randomItem || '';
}).volatile().readOnly();
}
DEMO
http://emberjs.jsbin.com/lulaki/35/edit?output
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
VISIBILITY OF SYSTEM STATUS
Jakob Nielsen — 10 Heuristics for User Interface Design
FLASH MESSAGES
Is it time for snacks yet?
Service
Routes Controllers
Message Component Message Component
SERVICE
Ember.get(this, 'flashes').success('Success!', 2000);
Ember.get(this, 'flashes').warning('...');
Ember.get(this, 'flashes').info('...');
Ember.get(this, 'flashes').danger('...');
Ember.get(this, 'flashes').addMessage('Custom message', 'myCustomType', 3000)
Ember.get(this, 'flashes').clearMessages();
SERVICE: PROPS
queue : Ember.A([]),
isEmpty : computed.equal('queue.length', 0),
defaultTimeout : 2000
SERVICE: PUBLIC API
success(message, timeout=get(this, 'defaultTimeout')) {
return this._addToQueue(message, 'success', timeout);
},
info(/* ... */) {
return ...;
},
warning(/* ... */) {
return ...;
},
danger(/* ... */) {
return ...;
},
addMessage(message, type='default', timeout=get(this, 'defaultTimeout')) {
return this._addToQueue(message, type, timeout);
}
SERVICE: PUBLIC API
clearMessages() {
let flashes = get(this, 'queue');
flashes.clear();
}
SERVICE: PRIVATE API
_addToQueue(message, type, timeout) {
let flashes = get(this, 'queue');
let flash = this._newFlashMessage(this, message, type, timeout);
flashes.pushObject(flash);
}
SERVICE: PRIVATE API
_newFlashMessage(service, message, type='info', timeout=get(this, 'defaultTimeout')) {
Ember.assert('Must pass a valid flash service', service);
Ember.assert('Must pass a valid flash message', message);
return FlashMessage.create({
type : type,
message : message,
timeout : timeout,
flashService : service
});
}
FLASH MESSAGE
FLASH MESSAGE: PROPS
isSuccess : computed.equal('type', 'success'),
isInfo : computed.equal('type', 'info'),
isWarning : computed.equal('type', 'warning'),
isDanger : computed.equal('type', 'danger'),
defaultTimeout : computed.alias('flashService.defaultTimeout'),
queue : computed.alias('flashService.queue'),
timer : null
FLASH MESSAGE: LIFECYCLE HOOK
_destroyLater() {
let defaultTimeout = get(this, 'defaultTimeout');
let timeout = getWithDefault(this, 'timeout', defaultTimeout);
let destroyTimer = run.later(this, '_destroyMessage', timeout);
set(this, 'timer', destroyTimer);
}.on('init')
FLASH MESSAGE: PRIVATE API
_destroyMessage() {
let queue = get(this, 'queue');
if (queue) {
queue.removeObject(this);
}
this.destroy();
}
FLASH MESSAGE: PUBLIC API & OVERRIDE
destroyMessage() {
this._destroyMessage();
},
willDestroy() {
this._super();
let timer = get(this, 'timer');
if (timer) {
run.cancel(timer);
set(this, 'timer', null);
}
}
Lj DEPENDENCY INJECTION
import FlashMessagesService from '...';
export function initialize(_container, application) {
application.register('service:flash-messages', FlashMessagesService, { singleton: true });
application.inject('controller', 'flashes', 'service:flash-messages');
application.inject('route', 'flashes', 'service:flash-messages');
}
export default {
name: 'flash-messages-service',
initialize: initialize
};
COMPONENT
COMPONENT: TEMPLATE
{{#if template}}
{{yield}}
{{else}}
{{flash.message}}
{{/if}}
COMPONENT: PUBLIC API
export default Ember.Component.extend({
classNames: [ 'alert', 'flashMessage' ],
classNameBindings: [ 'alertType' ],
alertType: computed('flash.type', function() {
let flashType = get(this, 'flash.type');
return `alert-${flashType}`;
}),
click() {
let flash = get(this, 'flash');
flash.destroyMessage();
}
});
USAGE
{{#each flashes.queue as |flash|}}
{{flash-message flash=flash}}
{{/each}}
{{#each flashes.queue as |flash|}}
{{#flash-message flash=flash}}
<h6>{{flash.type}}</h6>
<p>{{flash.message}}</p>
{{/flash-message}}
{{/each}}
DEMO
http://emberjs.jsbin.com/ranewo/46/edit?js,output
$ ember install:addon ember-cli-flash
$ npm install --save-dev ember-cli-flash
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
DRAG AND DROP
Skip
Draggable Dropzone
Draggable Item
Draggable Item
Draggable Item
Controller
sendAction()
Route
COMPONENT/VIEW EVENTS
http://emberjs.com/api/classes/Ember.View.html#toc_event-names
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/
Drag_operations#draggableattribute
https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer#getData.28.29
DROPZONE
export default Ember.Component.extend({
classNames : [ 'draggableDropzone' ],
classNameBindings : [ 'dragClass' ],
dragClass : 'deactivated',
dragLeave(event) {
event.preventDefault();
set(this, 'dragClass', 'deactivated');
},
dragOver(event) {
event.preventDefault();
set(this, 'dragClass', 'activated');
},
drop(event) {
let data = event.dataTransfer.getData('text/data');
this.sendAction('dropped', data);
set(this, 'dragClass', 'deactivated');
}
});
DRAGGABLE ITEM
export default Ember.Component.extend({
classNames : [ 'draggableItem' ],
attributeBindings : [ 'draggable' ],
draggable : 'true',
dragStart(event) {
return event.dataTransfer.setData('text/data', get(this, 'content'));
}
});
{{ yield }}
<div class="selectedUsers">
{{#draggable-dropzone dropped="addUser"}}
<ul class="selected-users-list">
{{#each selectedUsers as |user|}}
<li>{{user.fullName}}</li>
{{/each}}
</ul>
{{/draggable-dropzone}}
</div>
<div class="availableUsers">
{{#each users as |user|}}
{{#draggable-item content=user.id}}
<span>{{user.fullName}}</span>
{{/draggable-item}}
{{/each}}
</div>
actions: {
addUser(userId) {
let selectedUsers = get(this, 'selectedUsers');
let user = get(this, 'model').findBy('id', parseInt(userId));
if (!selectedUsers.contains(user)) {
return selectedUsers.pushObject(user);
}
}
}
DEMO
http://emberjs.jsbin.com/denep/18/edit?js,output
TL;DR
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
DESIGN IS HOW IT WORKS
GOOD DESIGN IS REACTIVE
GOOD DESIGN IS PLAYFUL
GOOD DESIGN IS INFORMATIVE
GOOD DESIGN IS INTUITIVE
AMBITIOUS UX FOR
AMBITIOUS APPS
EMBERCONF 2015
Lauren Elizabeth Tan
@sugarpirate_ @poteto
Makes ambitious UX easy (and fun!)
Design is how it works
Follow @sugarpirate_
bit.ly/sugarpirate
Thank you!
Lauren Elizabeth Tan
@sugarpirate_ @poteto

Weitere ähnliche Inhalte

Was ist angesagt?

7 client-state manipulation
7   client-state manipulation7   client-state manipulation
7 client-state manipulation
drewz lin
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv
 
8 sql injection
8   sql injection8   sql injection
8 sql injection
drewz lin
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
deimos
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Luka Zakrajšek
 
Remy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQueryRemy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQuery
deimos
 

Was ist angesagt? (20)

Frontends w ithout javascript
Frontends w ithout javascriptFrontends w ithout javascript
Frontends w ithout javascript
 
Node.js server-side rendering
Node.js server-side renderingNode.js server-side rendering
Node.js server-side rendering
 
7 client-state manipulation
7   client-state manipulation7   client-state manipulation
7 client-state manipulation
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
8 sql injection
8   sql injection8   sql injection
8 sql injection
 
Android ax app wcf
Android ax app wcfAndroid ax app wcf
Android ax app wcf
 
Android+ax+app+wcf
Android+ax+app+wcfAndroid+ax+app+wcf
Android+ax+app+wcf
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
 
Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]
 
Intro to computer vision in .net update
Intro to computer vision in .net   updateIntro to computer vision in .net   update
Intro to computer vision in .net update
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Remy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQueryRemy Sharp The DOM scripting toolkit jQuery
Remy Sharp The DOM scripting toolkit jQuery
 
Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and ExperiencedAngular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
 
GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with Vaadin
 
TLDR - OAuth
TLDR - OAuthTLDR - OAuth
TLDR - OAuth
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
 
Pyramid REST
Pyramid RESTPyramid REST
Pyramid REST
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytv
 
Intro to computer vision in .net
Intro to computer vision in .netIntro to computer vision in .net
Intro to computer vision in .net
 

Ähnlich wie EmberConf 2015 – Ambitious UX for Ambitious Apps

Emberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsEmberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applications
ColdFusionConference
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
OSCON Byrum
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
Eldar Djafarov
 

Ähnlich wie EmberConf 2015 – Ambitious UX for Ambitious Apps (20)

Sencha Touch - Introduction
Sencha Touch - IntroductionSencha Touch - Introduction
Sencha Touch - Introduction
 
Crie seu sistema REST com JAX-RS e o futuro
Crie seu sistema REST com JAX-RS e o futuroCrie seu sistema REST com JAX-RS e o futuro
Crie seu sistema REST com JAX-RS e o futuro
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
2015 ZendCon - Do you queue
2015 ZendCon - Do you queue2015 ZendCon - Do you queue
2015 ZendCon - Do you queue
 
Emberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsEmberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applications
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
The Future of Responsive Design Standards
The Future of Responsive Design StandardsThe Future of Responsive Design Standards
The Future of Responsive Design Standards
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Ember.js for a CakePHP Developer
Ember.js for a CakePHP DeveloperEmber.js for a CakePHP Developer
Ember.js for a CakePHP Developer
 
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
Effectively Testing Services - Burlington Ruby Conf
Effectively Testing Services - Burlington Ruby ConfEffectively Testing Services - Burlington Ruby Conf
Effectively Testing Services - Burlington Ruby Conf
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 

EmberConf 2015 – Ambitious UX for Ambitious Apps