Code Monkey home page Code Monkey logo

wq / wq.app Goto Github PK

View Code? Open in Web Editor NEW
116.0 17.0 32.0 8.39 MB

๐Ÿ’ป๐Ÿ“ฑ wq's app library: a JavaScript framework powering offline-first web & native apps for geospatial data collection, mobile surveys, and citizen science. Powered by Redux, React, Material UI and Maplibre GL.

Home Page: https://wq.io/wq.app/

License: MIT License

CSS 0.10% JavaScript 98.53% Python 1.28% Shell 0.09%
wq-framework mobile-app offline-first data-collection citizen-science offline gis mobile geospatial survey

wq.app's Introduction

wq

wq is a modular framework for field data collection and surveys via offline-capable mobile web apps.

Getting Started

wq can be installed via GitHub, Docker, PyPI, NPM, or a <script> tag via CDN. See the documentation for more information on getting started.

Dev Container (recommended)

  1. Go to https://github.com/wq/wq-docker-template
  2. Select "Use this template" -> "Create a new repository"
  3. Open the dev container via GitHub Codespaces or Docker Desktop

Docker Base Image

docker run ghcr.io/wq/base:main

Python

python3 -m venv venv
. venv/bin/activate
python -m pip install wq
wq create myproject

Node

npm init @wq myproject

CDN

<script type="module">
    import wq from 'https://unpkg.com/wq';
    wq.init({});
</script>

Features

wq is made up of the following submodules, which are maintained as separate packages.

Module Github PyPI npm Description
wq wq/wq wq wq Top level package (specifies submodules as dependencies)
wq.app wq/wq.app wq.app @wq/app A JavaScript+Python library for building robust offline-capable HTML5 data entry apps.
wq.build wq/wq.build wq.build wq command line interface.
wq.create wq/wq.create wq.create @wq/create Project template and scaffolding tools.
wq.db wq/wq.db wq.db Django REST framework extension with design patterns for CRUD APIs.

wq.app's People

Contributors

ast0815 avatar jjeurissen avatar sheppard avatar tomaszn avatar tubaman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wq.app's Issues

Configuration option to return to view

When I edit an annotation, upon saving, it returns to the annotation-detail page. I would like to have a configuration option that will let me choose where to redirect. Perhaps it could be a parameter for app.router.customize_page?

ensure jquery mobile is always initialized?

wq/router.js ensures that jQuery Mobile is not initialized until all routes have been set up. This is useful for ensuring pageshow events work as expected, but makes apps a bit more fragile if anything breaks while configuring routes. The main time this becomes an issue is when using class='ui-page' to avoid a FOUC: the CSS will load and hide the div, but then jQM will never be able to un-hide it.

It might be good to have a fallback function that executes after 500-1000 ms to ensure that jQM is initialized even if the rest of the code fails. The alternative would be to recommend not using class='ui-page' and just rely on ensuring simple HTML is able to function.

Marking as "enhancement" as this isn't strictly a bug in the library (it usually only shows up when there is a bug in application code).

use promises

There are a few places where promises would provide significant benefit over the current callback management routines, in particular in store.js and app.js. Perhaps the q library would be useful.

fully JSON based attachment configuration

Move the attachmentTypes configuration from being JavaScript hardcoded in wq/app.js to JSON embedded in the the wq configuration object.

For example,

var attachmentTypes = {
    relationship: {
        'predicate': 'related',
        'type': 'relationshiptype',
        'getTypeFilter': function(page, context) {
            /* jshint unused: false */
            return {'from_type': page};
        },
        'getChoiceList': function(type, context) {
            /* jshint unused: false */
            return type.to_type;
        },
        'getChoiceListFilter': function(type, context) {
            /* jshint unused: false */
            return {};
        },
        'getDefaults': function(type, context) {
            /* jshint unused: false */
            return {
                'type_label': type.name,
                'to_type': type.to_type
            };
        }
    }
};

might become:

{
    "pages": {
        "relationship": {
            "name": "relationship",
            "url": "relationships",
            "list": true,
            "parents": {
                "relationshiptype": [
                    "type"
                ]
            },
            "children": [],

            "attachment": {
                "predicate": "related",
                "type": "relationshiptype",
                "typeFilter": {
                    "from_type": "{{page}}"
                },
                "choiceListPage": "{{type.to_type}}",
                "choiceListFilter": {},
                "getDefaults": {
                    "type_label": "{{type.name}}",
                    "to_type": "{{type.to_type}}",
                }
          }
    }
}

wq/app.js breaks if offline storage is disabled

The new localForage-powered wq/store.js, and by extension wq/app.js, will fail if offline storage is disabled or unavailable. This is similar to #37, but the mechanism for handling it will be a bit different. One option would be to find/create a localForage "driver" that stores everything in memory. Another potential workaround would be to do something like this:

localForage.getItem('test').then(function() {
    // Successful, initialize wq/app.js
    app.init(config).then(function() {
        app.jqmInit();
        app.prefetchAll();
    });
}, app.jqmInit); // Failed; initialize "vanilla" jQuery Mobile

This assumes a wq.db-style backend, i.e. that the HTML templates and URL structure were created to render on the server with progressive enhancement in mind.

This is related to #40, except that the error is predictable (easily triggered by disabling cookies on iOS).

wq/app.js: form support for custom server actions

Add support for custom REST API actions, e.g. defined via an DRF @action decorator. Then you could define a form like this and have it work via a JSON AJAX call in wq/app.js:

<form action="/listurl/itemid/customaction" method="post">

use official repos for external deps?

Specifically, stop vendoring custom versions of external libraries in js/lib, and instead reference the actual repos (or maintained forks if necessary). Could probably use volojs (or bower) for dependency resolution.

Choices from Drop-Downs

The choice fields for drop-downs when they are declared on the model do not display the selected item.

wq start

Need an easy way to start a new project (including a shell app.build.json) from the command line.

use prototypes

For example, overwriting ds.save requires a hack:

define(['wq/store'], function(ds) {

var _dsSave = ds.save;
ds.save = function(data, id, callback) {
    // custom code ...
    _dsSave(data, id, callback);
}

});

With prototypes, this could become:

define(['wq/store'], function(ds) {

ds.save = function(data, id, callback) {
    // custom code ...
    ds.prototype.save(data, id, callback);
}

});

See #20.

wq/online Android Issue

When using wq/online on Android devices, the online.js module is sometimes offline, even when online. This results in items going into the outbox.

It seems that navigator.onLine does not always work reliably. I recommend we make an AJAX request to determine if the status is online as a fail safe.

workarounds for blob support in android 4.3 and earlier

Due to a bug in Android 4.3 and earlier, wq/outbox.js isn't able to upload offline-stored files via AJAX on those versions. Android 4.4 and newer versions are unaffected.

Workarounds include:

A better solution would be to fix this within wq/store.js to avoid the need for these workarounds. We'd detect the bug and then upload the file as a base64-encoded string if needed. The REST API (e.g. wq.db) would need to be modified to support file uploads in this format.

deprecate pagination in wq/store.js?

Real-world use cases so far have almost always had at most 0 or 1 pages of data stored locally, with subsequent pages rendered on the server. Even if there is a use case for JSON pagination, it's not clear what benefit there is to having each page stored separately on the client - if anything they should be stored in the same place.

don't cache jquery mobile fallback PNG images

Ensure that the automatically generated application cache does not include references to the fallback icon images from jQuery Mobile. They're included now since they're listed in the CSS (though the rule that lists them would normally not be active).

wq/store.js: re-evaluate and potentially overhaul

As the first major wq.app module(77f8903#diff-16), wq/store.js is unique in that it is the only major module with no external dependencies (other than shims and jQuery.ajax, the latter which should/could be factored out). It's time to evaluate whether there are any popular third-party localStorage-persisted Model libraries that have arisen in the last 2 years or so that fulfill similar needs and would be worth incorporating.

Specifically, the following actions need to be taken:

  • Fully document wq/store.js' existing functionality and API
  • Evaluate third party alternatives, and whether any have the same or comparable functionality
  • If a replacement is found, determine whether to keep wq/store.js as a compatibility wrapper, or switch to using the new library directly
  • If no similar libraries can be found, document why wq/store.js is unique
  • In either case, consider splitting out ds.getList() into a separate module (probably wq/model.js)

py3k

Update to Python 3.

fully JSON based map configuration

Like #38, but for wq/map.js. This would allow changing at least basemaps and GeoJSON layers via only map config.

This might prove difficult for things like map.config.maps[page].onshow and layerConf.oneach, which are best implemented as JS functions. I guess there's always eval()...

wq/chart.js: breaks in data

The line charts should be broken into separate segments when there is a significant* gap in the data (e.g. several months in an otherwise daily dataset).

*The definition of significant would need to be computed automatically and customizable.

Error when trying to Build

When I try to build, I get this error:

Now opening... ../htdocs-build/build.txt
Traceback (most recent call last):
  File "/Users/josh/.virtualenvs/wq1/bin/wq", line 9, in <module>
    load_entry_point('wq.core==0.8.0', 'console_scripts', 'wq')()
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 700, in __call__
    return self.main(*args, **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 680, in main
    rv = self.invoke(ctx)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/wq/core/decorators.py", line 19, in invoke
    return super(ConfigGroup, self).invoke(ctx)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 1027, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 873, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/decorators.py", line 63, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/decorators.py", line 16, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/wq/app/build/builder.py", line 56, in build
    ctx.invoke(appcache, version=version)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/decorators.py", line 63, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/click/core.py", line 508, in invoke
    return callback(*args, **kwargs)
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/wq/app/build/appcache.py", line 48, in appcache
    s_js, b_js = _parse_js_buildfile(outdir + '/build.txt')
  File "/Users/josh/.virtualenvs/wq1/lib/python2.7/site-packages/wq/app/build/appcache.py", line 80, in _parse_js_buildfile
    text = open(filename).read()
IOError: [Errno 2] No such file or directory: '../htdocs-build/build.txt'

It's obviously looking for build.txt. Where is this build.txt file? What creates build.txt in the first place?

factor out node dependency

As discussed in etianen/django-require#28, it would be nice to have a generic Python lib for executing r.js (or JavaScript in general). This lib could check the system for node, rhino or perhaps anything else that can execute JavaScript code.

Having a separate library in PyPI would also provide a nice succinct way to say "this lib requires the ability to execute JavaScript".

Issue Running deploy.sh on OSX Mavericks with Python 2.7.5

I am currently trying to get wq.app and wq.db up-and-running on Mac OSX Mavericks. I am trying at the moment to run deploy.sh. When deploy, in turn, runs manage.py, I get this error:

env: python3: No such file or directory

This makes perfect sense, as I am not using python 3, but rather 2.7.5. So, I am wondering, should I upgrade to Python3, or can I simply change this directive #!/usr/bin/env python3 to an identifier that references Pyhon 2.7.5?

Or... would I be better served running ubuntu 14.04 LTS like is used in all the documentation? (I'd rather not use a totally different os for development and have to use a whole new set of tools, but if I have to, I will). What do you think?

Errors when trying to optimize

I have installed the sample application wq.app. I am currently trying to build it. When I go to the app folder, then type wq optimize, I get this:

####################
Optimizing with r.js
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/highlight.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/jquery.mobile.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/jquery.mobile.icons.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/jquery.mobile.structure.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/leaflet.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/leaflet.draw.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/lib/leaflet.markercluster.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/themes.css
Optimizing (standard.keepLines.keepWhitespace) CSS file: /Users/user/Development/python/wqprojectdir/htdocs-build/css/wqproject.css
lib/leaflet.css
  URL not a relative URL, skipping: #default#VML

Tracing dependencies for: wqproject
Error: ENOENT, no such file or directory '/Users/user/Development/python/wqprojectdir/htdocs-build/js/data/config.js'
In module tree:
    wqproject
      wqproject/main
        wqproject/config

Error: Error: ENOENT, no such file or directory '/Users/user/Development/python/wqprojectdir/htdocs-build/js/data/config.js'
In module tree:
    wqproject
      wqproject/main
        wqproject/config

    at Error (native)

I went through the other build steps that come before optimize, and they all worked out fine. What am I missing?

wq/app.js: always prefetch lists?

This pattern is quite common at the start of almost every wq/app.js-powered application:

for(var key in app.config.pages) {
    if (app.config.pages[key].list) {
        var url = app.config.pages[key].url;
        ds.prefetch({'url': url});
    }
}

Perhaps it should be the default?

wq/map.js: L.Icon.Default.imagePath might be undefined when module loads

The best solution would be to compute it automatically based on the location of the CSS file (rather than the JS location which is what Leaflet tries to do).

Either way, should probably change wq/map.js so that it works even if L.Icon.Default.imagePath is changed after the module loads (e.g. by the user's own map module).

use current auth data when syncing outbox

Need to support this workflow:

  • Offline, not logged in
  • Create item
  • Go online
  • Authenticate
  • Sync outbox

This will also help for cases when users need to re-authenticate for whatever reason.

May need to have a notion of "ownership" of items so you can't get at someone else's outbox?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.