Ejemplo n.º 1
0
    async def layout(request: web.Request):
        next_url = request.query.get('next_url') or default_redirect
        error = request.query.get('err')

        footer = core.Container(
            'Invalid credentials',
            style={'color': 'red', 'padding': '0.5rem'},
            identity='login-error'
        ) if error else UNDEFINED

        return core.Container([
            auth.Login(
                '/auth/login',
                method='post',
                identity='login-form',
                next_url=next_url,
                bordered=True,
                header=core.Html('h2', 'Please sign in'),
                footer=footer,
                style={
                    'padding': '2rem',
                }
            ),
        ], style={
            'display': 'flex',
            'justifyContent': 'center',
            'alignItems': 'center',
            'width': '100%',
            'marginTop': '4rem'
        })
Ejemplo n.º 2
0
async def layout(request: web.Request):
    return core.Container([
        core.Container(request.get('dummy', 'foobar'),
                       identity='request-output'),
        core.Container(identity='cookie-output'),
        core.Button('Set from cookie', identity='cookie-setter')
    ])
Ejemplo n.º 3
0
async def on_click(ctx: BindingContext):
    await ctx.set_aspect(
        'output',
        children=core.Container([
            core.Container('from click', identity='trigger'),
            core.Input(value=ctx.trigger.value,
                       type='number', identity='store-clicks')
        ])
    )
Ejemplo n.º 4
0
def test_page_url_conflict():
    page_one = Page('one', core.Container())
    page_two = Page('two', core.Container(), url='/one')

    app = Dazzler(__name__)
    with pytest.raises(PageConflictError) as context:
        app.add_page(page_one, page_two)

    assert context.value.args[0] == 'Duplicate page url: two@/one'
Ejemplo n.º 5
0
async def on_any_click(ctx: BindingContext):
    await ctx.set_aspect(
        re.compile(r'output\d'),
        children=f'clicked from button {ctx.trigger.identity}')
    output = []
    for identity, aspects in ctx.states.items():

        for aspect_name, aspect_value in aspects.items():
            output.append(
                core.Container(f'{aspect_name}@{identity}: {aspect_value}',
                               identity=f'{aspect_name}-{identity}-output'))

    # FIXME Setting the array directly on children trigger
    #  the same identity bug #53
    await ctx.set_aspect('state-output', children=core.Container(output))
Ejemplo n.º 6
0
async def test_page_meta_attributes(start_page, browser):
    meta = [
        {
            'name': 'description',
            'content': 'test dazzler'
        },
        {
            'name': 'custom',
            'content': 'customized'
        },
    ]
    await start_page(
        Page(name='meta',
             layout=core.Container('Hello', identity='layout'),
             meta_tags=meta))
    await asyncio.sleep(0.001)
    meta_tags = await browser.wait_for_elements_by_css_selector('meta')

    # Meta charset + http-equiv always present (+2)
    assert len(meta_tags) == 4

    for i in range(2, len(meta_tags)):
        meta_dict = meta[i - 2]
        meta_tag = meta_tags[i]
        for k, v in meta_dict.items():
            assert meta_tag.get_attribute(k) == v
Ejemplo n.º 7
0
async def on_concat(ctx: BindingContext):
    await ctx.set_aspect(
        'list-box',
        concat=[
            core.Container(f'concat-{x}', class_name='item concat')
            for x in range(await ctx.get_aspect('index-input', 'value'))
        ])
Ejemplo n.º 8
0
async def layout(request: web.Request):
    user = request.cookies.get('logged-user')
    if user:
        return core.Container([
            core.Html('h1', f'Logged in as {user}', identity='login-label'),
            auth.Logout('/login/logout', identity='logout'),
        ])
    return core.Container([
        auth.Login(
            '/login/login-perform',
            method='post',
            identity='login-form',
            bordered=True,
            header=core.Html('h3', 'Please login', identity='login-label'),
        ),
    ])
Ejemplo n.º 9
0
def session_app():
    app = Dazzler(__name__)
    app.config.session.duration = 3
    app.config.secret_key = uuid.uuid4().hex

    page = Page(__name__,
                core.Container(
                    [core.Container(identity='session-output', clicks=1)]),
                url='/')

    @page.bind(Trigger('session-output', 'clicks'))
    async def on_session(ctx: BindingContext):
        await ctx.set_aspect('session-output', children=ctx.session.session_id)

    app.add_page(page)

    return app
Ejemplo n.º 10
0
async def on_insert(ctx: BindingContext):
    index = await ctx.get_aspect('index-input', 'value')
    await ctx.set_aspect('list-box',
                         insert={
                             'index':
                             index,
                             'item':
                             core.Container('inserted',
                                            class_name='item insert')
                         })
Ejemplo n.º 11
0
async def test_session(start_visit, browser, backend):
    app = Dazzler(__name__)
    app.config.session.enable = False
    app.config.session.duration = 3
    app.middlewares.append(SessionMiddleware(app, backend=backend(app)))

    page = Page(__name__,
                url='/',
                layout=core.Container([
                    core.Button('Click', identity='session-click'),
                    core.Container(identity='session-output'),
                    core.Button('Remove session', identity='remove-session'),
                ]))

    @page.bind(Trigger('session-click', 'clicks'))
    async def on_session(ctx: BindingContext):
        session = ctx.request['session']

        clicks = await session.get('clicks') or 0
        clicks += 1
        await session.set('clicks', clicks)

        await ctx.set_aspect('session-output', children=f'Clicked {clicks}')

    @page.bind(Trigger('remove-session', 'clicks'))
    async def on_remove(ctx: BindingContext):
        session = ctx.request['session']
        await session.delete('clicks')

    app.add_page(page)

    await start_visit(app)

    for i in range(1, 4):
        await browser.get('http://localhost:8150/')
        await browser.click('#session-click')
        await browser.wait_for_text_to_equal('#session-output', f'Clicked {i}')

    # Delete session item
    await browser.click('#remove-session')
    await browser.click('#session-click')
    await browser.wait_for_text_to_equal('#session-output', 'Clicked 1')
Ejemplo n.º 12
0
def auth_app():
    app = Dazzler(__name__)
    page = Page('test-auth',
                core.Container([
                    core.Html('h2', 'logged-in', identity='header'),
                    core.Container(identity='username-output'),
                    _auth.Logout('/auth/logout', identity='logout')
                ]),
                url='/',
                require_login=True)

    @page.bind(Trigger('header', 'children'))
    async def on_username(ctx):
        user = ctx.request['user']
        await ctx.set_aspect('username-output', children=user.username)

    app.add_page(page)
    app.config.session.backend = 'Redis'

    DazzlerAuth(app, DummyAuthenticator())

    return app
Ejemplo n.º 13
0
async def test_package_route(start_page, browser):
    async def package_route(_):
        return web.Response(body='<html><head></head><body>'
                            '<div id="content">Package route</div>'
                            '</body></html>',
                            content_type='text/html')

    await start_page(
        Page('package',
             core.Container(),
             routes=[Route('/package-route', package_route)]))

    await browser.get('http://localhost:8150/package-route')
    await browser.wait_for_text_to_equal('#content', 'Package route')
Ejemplo n.º 14
0
async def test_page_routes(start_page, browser):

    page = Page('page-routes', core.Container())

    # pylint: disable=unused-variable
    @page.route('/page-route')
    async def page_route(_):
        return web.Response(body='<html><head></head><body>'
                            '<div id="content">Page route</div>'
                            '</body></html>',
                            content_type='text/html')

    await start_page(page)

    await browser.get('http://localhost:8150/page-routes/page-route')
    await browser.wait_for_text_to_equal('#content', 'Page route')
Ejemplo n.º 15
0
async def test_page_requirements_package_override(start_page, browser):
    # Overriding the package is an optimization if some pages uses big bundles
    # and others pages are more lightweight, down the line maybe add
    # on-demand loading of requirements, it's already set up for it.
    # noinspection PyUnresolvedReferences
    from tests.components import spec_components as spec  # noqa: F401

    page = Page(__name__,
                core.Container('Rendered'),
                packages=['dazzler_core'])
    await start_page(page)
    await browser.wait_for_element_by_css_selector('.dazzler-rendered')

    scripts = await browser.wait_for_elements_by_css_selector('script')
    for script in scripts:
        src = script.get_attribute('src')
        assert 'dazzler_test' not in src
Ejemplo n.º 16
0
async def test_auth_from_configs(start_visit, browser):
    app = Dazzler(__name__)
    app.config.authentication.enable = True
    app.config.session.backend = 'Redis'
    app.config.authentication.authenticator = \
        'tests.test_dazzler_auth:DummyAuthenticator'

    page = Page(__name__,
                core.Container('my-page', identity='content'),
                require_login=True,
                url='/')
    app.add_page(page)

    await start_visit(app)
    await browser.get('http://localhost:8150/')

    await proceed_login(browser, 'AgentSmith', 'SuperSecret1')
    await browser.wait_for_text_to_equal('#content', 'my-page')
Ejemplo n.º 17
0
"""
Page markdown of dazzler
Created 2019-08-19
"""
from dazzler.components import core, markdown as md
from dazzler.system import Page

text = '''
# Foo
## Bar
[google](http://google.com)

```jsx
const Foo = props => <div>{props.text}</div>;
```
'''

page = Page(
    __name__,
    core.Container([
        md.Markdown(text, identity='markdown'),
        md.CodeBlock(value=text, language='md')
    ]))
Ejemplo n.º 18
0
"""
Page progress of dazzler
Created 2019-06-26
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    __name__,
    core.Container([
        core.ProgressBar(identity='progress',
                         minimum=0,
                         high=80,
                         low=20,
                         maximum=100,
                         rounded=True,
                         optimum=21,
                         striped=True,
                         progress_text='percent'),
        core.Button('add progress', identity='progress-btn'),
        core.Container(identity='counter')
    ]))


@page.bind(Trigger('progress-btn', 'clicks'), State('progress', 'value'))
async def on_meter(ctx: BindingContext):
    new_value = (ctx.states['progress']['value'] or 0) + 1
    await ctx.set_aspect('progress', value=new_value)
    await ctx.set_aspect('counter', children=new_value)
Ejemplo n.º 19
0
"""
Page get_aspect_error of dazzler
Created 2019-06-15
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext
from dazzler.errors import GetAspectError

page = Page(
    __name__,
    core.Container([
        core.Button('click error', identity='click-error'),
        core.Container(identity='error-output')
    ]))


@page.bind(Trigger('click-error', 'clicks'))
async def trigger_error(ctx: BindingContext):
    try:
        await ctx.get_aspect('invalid', 'error')
    except GetAspectError as err:
        await ctx.set_aspect('error-output', children=err.args[0])
Ejemplo n.º 20
0
"""
Page initial_trigger of dazzler
Created 2019-06-15
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    'initial-trigger',
    core.Container([
        core.Input(value=10, identity='input'),
        core.Container(identity='output'),
        core.Input(value=88, identity='state'),
        core.Container(identity='state-output')
    ]))


@page.bind(Trigger('input', 'value'), State('state', 'value'))
async def on_value(context: BindingContext):
    await context.set_aspect('output',
                             children=f'Input {context.trigger.value}')
    await context.set_aspect(
        'state-output', children=F'State {context.states["state"]["value"]}')
Ejemplo n.º 21
0
async def layout(_):
    return core.Container('Layout as function', identity='layout')
Ejemplo n.º 22
0
from dazzler import Dazzler
from dazzler.components import core
from dazzler.system import Page

app = Dazzler(__name__)

for num in ('one', 'two', 'three', 'four'):
    page = Page(
        name=num,
        layout=core.Container(f'Page {num}', identity='content'),
        title=f'Page {num}',
    )

    app.add_page(page)


if __name__ == '__main__':
    app.start('-v --debug 1'.split())
Ejemplo n.º 23
0
"""
Page icons of dazzler
Created 2021-06-13
"""
from dazzler.components import core, icons
from dazzler.system import Page

page = Page(
    __name__,
    core.Container([
        icons.IconLoader([]),
        icons.LinearIconPack(),
        icons.FoundIconPack(),
        icons.OpenIconicPack(),
        icons.TypiconsPack(),
        core.Container(icons.Icon('lnr-home'), ),
        core.Container(icons.Icon('fi-home')),
        core.Container(icons.Icon('oi-bug')),
        core.Container(icons.Icon('typcn-globe')),
    ]))
Ejemplo n.º 24
0
async def on_click(context: BindingContext):
    await context.set_aspect('output',
                             children=core.Container('from binding',
                                                     id='from-binding'))
Ejemplo n.º 25
0
from dazzler import Dazzler
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext

page = Page(name='page',
            url='/',
            layout=core.Container([
                core.Button('click', identity='clicker'),
                core.Container('output', identity='output')
            ]))

app = Dazzler(__name__)
app.add_page(page)


@page.bind(Trigger('clicker', 'clicks'))
async def on_click(context: BindingContext):
    await context.set_aspect('output',
                             children=core.Container('from binding',
                                                     id='from-binding'))


if __name__ == '__main__':
    app.start('-v --debug=1 --port=8151'.split())
Ejemplo n.º 26
0
from dazzler.components import core, extra
from dazzler.system import Page, BindingContext

page = Page(
    __name__,
    core.Container([
        extra.TreeView([
            'item12', {
                'identifier':
                'nest',
                'label':
                'nest',
                'items': [
                    'nested1', 'nested2', {
                        'label': 'subnest',
                        'identifier': 'subnest',
                        'items': ['sub1', 'sub2']
                    }
                ],
            }
        ],
                       identity='treeview'),
        core.Container(identity='output')
    ]))


@page.bind('selected@treeview')
async def on_selected(ctx: BindingContext):
    await ctx.set_aspect('output', children=ctx.trigger.value)
Ejemplo n.º 27
0
            [1, 2, 3, 4],
            [1, 'foo', 'bar', 4],
            [{'arr': [1, 2, 3], 'foo': 'bar'}],
            [[1, 2, 4],  ['foo', 'bar']]
        ]
    )
] for i in range(0, 4)), 2)))

page = Page(
    __name__,
    core.Container([
        core.Store(identity='empty-store'),
        core.Store(data={'foo': 'bar'}, identity='initial-store'),
        core.Button('click', identity='click'),
        core.Container(identity='click-output'),
        core.Container(identity='initial-output'),
        core.Button('type-click', identity='type-click'),
        core.Store(identity='type-store'),
        core.Container(identity='type-output'),
        core.Button('get-aspect', identity='get-aspect-click'),
        core.Container(identity='get-aspect-output')
    ])
)


@page.bind(Trigger('initial-store', 'data'))
async def initial(ctx: BindingContext):
    await ctx.set_aspect(
        'initial-output',
        children=json.dumps(ctx.trigger.value)
    )
Ejemplo n.º 28
0
import asyncio
import json
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    'binding-tree',
    core.Container([
        core.Button('trigger', identity='trigger'),
        core.Container([
            core.Container([
                core.Input(identity=f'output-{i}', type='number')
                for i in range(1, 3)
            ]),
            core.Container([
                core.Input(identity=f'value-{i}', type='number')
                for i in range(1, 11)
            ]),
            core.Container('[]', identity='output'),
            core.Container(identity='done')
        ])
    ]))


@page.bind(Trigger('trigger', 'clicks'))
async def trigger_click(context: BindingContext):
    await context.set_aspect('output-1', value=1)
    # Got to alternate the inputs for the first set to complete and let
    # frontend to register the state and all,
    # so as long as this start after and the other delay
    # is a little higher it should be ok.
Ejemplo n.º 29
0
import functools

from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext

page = Page(
    'binding-chain',
    core.Container([
        core.Button(x, identity=f'trigger-{x}') for x in range(1, 21)
    ] + [core.Container(identity='output')])
)


async def update_next(context: BindingContext, num: int = 0):
    await context.set_aspect(
        f'trigger-{num+1}',
        clicks=1,
    )


@page.bind(Trigger('trigger-20', 'clicks'))
async def last_trigger(context: BindingContext):
    await context.set_aspect('output', children='output generated')


for i in range(1, 20):
    page.bind(Trigger(f'trigger-{i}', 'clicks'))(
        functools.partial(update_next, num=i)
    )
Ejemplo n.º 30
0
from dazzler import Dazzler
from dazzler.system import Page

from dazzler.components import core

app = Dazzler(__name__)
app.config.requirements.prefer_external = True

app.add_page(Page('index', core.Container('foo'), url='/'))