Commit f79c0f13 by Иван Кубота

Actions Controller

Store: valEqualOnly method that fires only when equality check is passed Observer once method. auto unsubscribe on first happened event Account page: save\restore slider position when user enters\leaves the page. Card: Generate action ACTION.CARD.LEARN_MORE when user clicks on "Изучить" button CardSlider: refactor to object. add save\restore methods. For saving and restoring current scroll position. Switch component: Generate beforeSwitch and afterSwitch events with (to, from) arguments If AfterSwitch is happened before app loaded - event would fire after load.
parent 5d0b3f30
const Action = function(fn) {
this.fn = fn;
};
Action.prototype = {
execute: function() {
this.fn.apply(this, arguments);
}
};
const ACTION = {
CARD: {
LEARN_MORE: new Action((item)=>{
store.set({
'navigation.current': 'InfoPage',
'navigation.data': item
});
})
},
Action
};
export default ACTION
export {ACTION};
...@@ -27,6 +27,15 @@ Observable.prototype = { ...@@ -27,6 +27,15 @@ Observable.prototype = {
const listener = listeners[ i ]; const listener = listeners[ i ];
listener.apply(this, [].slice.call(arguments, 1)); listener.apply(this, [].slice.call(arguments, 1));
} }
},
once: function(k, v) {
var _self = this,
wrap = function() {
v.apply(this, arguments);
_self.un(k, wrap)
};
this.on(k, wrap);
} }
}; };
typeof module === 'object' && (module.exports = Observable); typeof module === 'object' && (module.exports = Observable);
\ No newline at end of file
...@@ -168,7 +168,13 @@ Store.prototype = { ...@@ -168,7 +168,13 @@ Store.prototype = {
valEqual: function(key, val) { valEqual: function(key, val) {
const me = this; const me = this;
return function backwardCallback(update) { return function backwardCallback(update) {
me.equal(key, val, compareResult => update(compareResult)); me.equal(key, val, compareResult => {update(compareResult)});
}
},
valEqualOnly: function(key, val) {
const me = this;
return function backwardCallback(update) {
me.equal(key, val, compareResult => {compareResult && update(compareResult)});
} }
}, },
valTrue: function(key) { valTrue: function(key) {
......
...@@ -203,7 +203,7 @@ const Consts = { ...@@ -203,7 +203,7 @@ const Consts = {
MONTH_YEAR: "LLLL yyyy", MONTH_YEAR: "LLLL yyyy",
DAY_MONTH: "dd.MM", DAY_MONTH: "dd.MM",
}, },
} };
Consts.LOCAL_STORAGE.TOKEN.GET_TOKEN = (token) => `Bearer ${token}` Consts.LOCAL_STORAGE.TOKEN.GET_TOKEN = (token) => `Bearer ${token}`
...@@ -219,4 +219,6 @@ for(let key in Consts.API.ENDPOINTS){ ...@@ -219,4 +219,6 @@ for(let key in Consts.API.ENDPOINTS){
} }
export default Consts export default Consts
export const API = Consts.API; const API = Consts.API;
export {API};
export {Consts};
...@@ -16,7 +16,12 @@ export default function() { ...@@ -16,7 +16,12 @@ export default function() {
let dom = <div renderTo={document.body} cls="page-content"> let dom = <div renderTo={document.body} cls="page-content">
<view.block.Header/> <view.block.Header/>
{Switch({cls: 'page-content__inner', key: 'navigation.current'}, {Switch({
cls: 'page-content__inner',
key: 'navigation.current',
beforeSwitch: (val, old)=>{tmpStore.set('beforeNavigation', {from:old, to: val});},
afterSwitch: (val, old)=>{tmpStore.set('afterNavigation', {from:old, to: val});}
},
Object.keys(Page).reduce((store, pageName)=>{ Object.keys(Page).reduce((store, pageName)=>{
store[pageName] = new Page[pageName](); store[pageName] = new Page[pageName]();
return store; return store;
......
...@@ -2,8 +2,10 @@ import './card.scss'; ...@@ -2,8 +2,10 @@ import './card.scss';
import Eye from '/svg/eye.svg'; import Eye from '/svg/eye.svg';
import Button from "../button/Button"; import Button from "../button/Button";
import Format from "../format/Format"; import Format from "../format/Format";
import ACTION from "../../../controller/Action";
const noFn = ()=>{};
const Card = D.declare('view.cmp.Card', (cfg) => { const Card = D.declare('view.cmp.Card', (cfg) => {
const action = cfg.action || noFn;
return <div className={D.cls('card card--'+ return <div className={D.cls('card card--'+
(cfg.disabled?'disabled': (cfg.disabled?'disabled':
cfg.seen?'seen':cfg.type))}> cfg.seen?'seen':cfg.type))}>
...@@ -19,7 +21,7 @@ const Card = D.declare('view.cmp.Card', (cfg) => { ...@@ -19,7 +21,7 @@ const Card = D.declare('view.cmp.Card', (cfg) => {
<Eye width="20" height="13"/> <Eye width="20" height="13"/>
</div> </div>
: :
<Button class={"button card__button"} onclick={cfg.onclick}> <Button class={"button card__button"} onclick={()=>cfg.action(ACTION.CARD.LEARN_MORE)}>
<span>Изучить</span> <span>Изучить</span>
</Button> </Button>
) )
......
...@@ -3,6 +3,8 @@ const Switch = D.declare('Switch', (cfg, contentHash) => { ...@@ -3,6 +3,8 @@ const Switch = D.declare('Switch', (cfg, contentHash) => {
if(cfg.content){ if(cfg.content){
contentHash = cfg.content; contentHash = cfg.content;
} }
let {beforeSwitch, afterSwitch} = cfg;
if(Array.isArray(contentHash)){ if(Array.isArray(contentHash)){
if(contentHash.length === 0){ if(contentHash.length === 0){
if(cfg.content) if(cfg.content)
...@@ -23,12 +25,15 @@ const Switch = D.declare('Switch', (cfg, contentHash) => { ...@@ -23,12 +25,15 @@ const Switch = D.declare('Switch', (cfg, contentHash) => {
'cmp-switch', 'cmp-switch',
cfg.cls, cfg.cls,
{ 'cmp-switch__filled': val in contentHash } ) ) ) } ); { 'cmp-switch__filled': val in contentHash } ) ) ) } );
let oldValue;
(cfg.store || store).sub( cfg.key, (val)=> { (cfg.store || store).sub( cfg.key, (val)=> {
beforeSwitch && beforeSwitch(val, oldValue);
D.removeChildren(cmp); D.removeChildren(cmp);
if(val in contentHash) if(val in contentHash)
D.appendChild( cmp, contentHash[ val ] ); D.appendChild( cmp, contentHash[ val ] );
afterSwitch && (tmpStore.get('loaded') ? afterSwitch(val, oldValue) : tmpStore.once('loaded', ()=> afterSwitch(val, oldValue)));
oldValue = val;
}); });
return cmp; return cmp;
......
...@@ -6,10 +6,40 @@ import Card from "../../cmp/card/Card"; ...@@ -6,10 +6,40 @@ import Card from "../../cmp/card/Card";
import CardSlider from "../../cmp/cardSlider/CardSlider"; import CardSlider from "../../cmp/cardSlider/CardSlider";
const Account = D.declare('view.page.Account', () => { const Account = D.declare('view.page.Account', () => {
let Slider = new CardSlider( {
name: "newCardsSlider",
itemClick: ( item, action ) => {
action.execute( item );
},
return <div class="account-page">
items: _ => store.sub(
[
'loaded.cards',
'navigation.current',
tmpStore.bind( 'loaded' ),
tmpStore.bind( 'newCardsLoaded' ),
],
function( loadedCards, page, loaded, newCardsLoaded ){
console.log( loadedCards, page, loaded, newCardsLoaded )
if( newCardsLoaded !== loadedCards ){
if( loadedCards && page === 'Account' && loaded ){
_( cards
.getArray()
.filter( card => card.seen === false )
.sort( ( a, b ) => a.id - b.id )
);
tmpStore.set( 'newCardsLoaded', loadedCards )
}
}
}
)
} );
const dom = <div class="account-page">
<h1 class="readers-only">Страница личного кабинета сотрудника</h1> <h1 class="readers-only">Страница личного кабинета сотрудника</h1>
<div class="account-page__wrapper"> <div class="account-page__wrapper">
<div class="account-page__menu"> <div class="account-page__menu">
...@@ -21,118 +51,22 @@ const Account = D.declare('view.page.Account', () => { ...@@ -21,118 +51,22 @@ const Account = D.declare('view.page.Account', () => {
<div class="account-page__content-inner"> <div class="account-page__content-inner">
<div class="account-page__cards"> <div class="account-page__cards">
<h2 class="account-page__title">Новые карточки для вашей должности:</h2> <h2 class="account-page__title">Новые карточки для вашей должности:</h2>
<CardSlider {Slider}
items={_=> store.sub(
[
'loaded.cards',
'navigation.current',
tmpStore.bind('loaded')
],
(loadedCards, page, loaded,w)=>{
if(loadedCards && page === 'Account' && loaded)
_(cards
.getArray()
.filter(card=>card.seen === false)
.sort((a,b)=>a.id-b.id),
w+(w<1024?0:320+30*2+30*2)
)
})}
/>
{/* {(()=> {
let c = <div/>;
(async () => {
const result = await AsyncAuthAjax.get(API.ENDPOINTS.GET_USER_NEW_CARDS());
D.appendChild(c, result.map((item, n) =>
<div class="cards-list__item">
<Card
type={'product,info,other'.split(',')[n % 3]}
disabled={n % 5 === 0}
seen={n % 4 === 0}
title={item.name}
image={item.image}
/>
</div>
));
})();
return c
})()}*/}
{/*
<div class="cards-list__item">
<div class="card card--info">
<div class="card__image">
<img src="/uploads/images/card_product1.jpg" alt=""/>
</div>
<h3 class="card__title">Название карточки</h3>
<div class="card__footer">
<Button class={"button card__button"}>
<span>Изучить</span>
</Button>
</div>
</div>
</div>
<div class="cards-list__item">
<div class="card card--product">
<div class="card__image">
<img src="/uploads/images/card_product2.jpg" alt=""/>
</div>
<h3 class="card__title">Название карточки</h3>
<div class="card__footer">
<Button class={"button card__button"}>
<span>Изучить</span>
</Button>
</div>
</div>
</div>
<div class="cards-list__item">
<div class="card card--other">
<div class="card__image">
<img src="/uploads/images/card_product3.jpg" alt=""/>
</div>
<h3 class="card__title">Название карточки</h3>
<div class="card__footer">
<Button class={"button card__button"}>
<span>Изучить</span>
</Button>
</div>
</div>
</div>
<div class="cards-list__item">
<div class="card card--seen">
<div class="card__image">
<img src="/uploads/images/card_product4.jpg" alt=""/>
</div>
<h3 class="card__title">Название карточки</h3>
<div class="card__footer">
<div class="card__note">
<span>Просмотрена</span>
<Eye width="20" height="13" />
</div>
</div>
</div>
</div>
<div class="cards-list__item">
<div class="card card--disabled">
<div class="card__image">
<img src="/uploads/images/card-disabled.png" alt=""/>
</div>
<h3 class="card__title">Карточек нет</h3>
<div class="card__footer">
</div>
</div>
</div>*/}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>;
tmpStore.valEqualOnly('afterNavigation.to', 'Account')(function() {
Slider.restore();
});
tmpStore.valEqualOnly('beforeNavigation.from', 'Account')(function() {
Slider.save();
});
return dom;
}); });
export default Account; export default Account;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment