From 197e3a24f1f0baf758fa078c1053af6addc4aa29 Mon Sep 17 00:00:00 2001 From: cnouguier Date: Mon, 6 May 2024 08:49:56 +0000 Subject: [PATCH] Docs built from d3bad91a2bdcc6510f791b5c0d871f3528076ce6 --- 404.html | 2 +- about/contact.html | 2 +- about/contributing.html | 2 +- about/introduction.html | 2 +- about/license.html | 2 +- about/roadmap.html | 2 +- api/core/application.html | 2 +- api/core/components.html | 2 +- api/core/composables.html | 2 +- api/core/hooks.html | 2 +- api/core/introduction.html | 2 +- api/core/mixins.html | 2 +- api/core/services.html | 2 +- api/introduction.html | 2 +- api/map/components.html | 2 +- api/map/composables.html | 2 +- api/map/globe-mixins.html | 2 +- api/map/hooks.html | 2 +- api/map/introduction.html | 2 +- api/map/map-mixins.html | 77 +++++++++- api/map/mixins.html | 2 +- api/map/services.html | 2 +- architecture/component-view.html | 2 +- architecture/data-model-view.html | 2 +- architecture/global-architecture.html | 2 +- architecture/introduction.html | 2 +- architecture/main-concepts.html | 2 +- assets/api_map_map-mixins.md.cLyjeJ2i.js | 144 ++++++++++++++++++ assets/api_map_map-mixins.md.cLyjeJ2i.lean.js | 1 + guides/basics/introduction.html | 2 +- guides/development/configure.html | 2 +- guides/development/deploy.html | 2 +- guides/development/develop.html | 2 +- guides/development/publish.html | 2 +- guides/development/setup.html | 2 +- guides/development/test.html | 2 +- guides/introduction.html | 2 +- hashmap.json | 2 +- index.html | 2 +- tips/app-development.html | 2 +- tips/introduction.html | 2 +- tips/mobile-configuration.html | 2 +- tools/browsers.html | 2 +- tools/cli.html | 2 +- tools/db.html | 2 +- tools/documentation.html | 2 +- tools/infrastructure.html | 2 +- tools/introduction.html | 2 +- 48 files changed, 264 insertions(+), 48 deletions(-) create mode 100644 assets/api_map_map-mixins.md.cLyjeJ2i.js create mode 100644 assets/api_map_map-mixins.md.cLyjeJ2i.lean.js diff --git a/404.html b/404.html index a9df3286f..9c75acecb 100644 --- a/404.html +++ b/404.html @@ -17,7 +17,7 @@
Skip to content

404

PAGE NOT FOUND

But if you don't change your direction, and if you keep looking, you may end up where you are heading.
- + \ No newline at end of file diff --git a/about/contact.html b/about/contact.html index 20d50380a..24d71ba6a 100644 --- a/about/contact.html +++ b/about/contact.html @@ -43,7 +43,7 @@
Skip to content

Contact

Please feel free to join our slack channel using the invitation link.

- + \ No newline at end of file diff --git a/about/contributing.html b/about/contributing.html index 8f63c170b..86d205630 100644 --- a/about/contributing.html +++ b/about/contributing.html @@ -43,7 +43,7 @@
Skip to content

Contributing

Submission guidelines

Report a bug

Before creating an issue please make sure you have checked out the docs, you might want to also try searching Github. It's pretty likely someone has already asked a similar question.

Issues can be reported in the issue tracker.

Pull Requests

We love pull requests and we're continually working to make it as easy as possible for people to contribute.

We prefer small pull requests with minimal code changes. The smaller they are the easier they are to review and merge. A core team member will pick up your PR and review it as soon as they can. They may ask for changes or reject your pull request. This is not a reflection of you as an engineer or a person. Please accept feedback graciously as we will also try to be sensitive when providing it.

Although we generally accept many PRs they can be rejected for many reasons. We will be as transparent as possible but it may simply be that you do not have the same context or information regarding the roadmap that the core team members have. We value the time you take to put together any contributions so we pledge to always be respectful of that time and will try to be as open as possible so that you don't waste it.

Commit message guidelines

We follow the Conventional commits specifications which provides a set of rules to make commit messages more readable when looking through the project history. But also, we use the git commit messages to generate the change log.

Commit message format

The commit message should be structured as follows:

<type>: <subject> [optional `breaking`]

Where type must be one of the following:

  • build: changes that affect the build system (external dependencies)
  • ci: changes to our CI configuration files and scripts
  • chore: changes that affect the project structure
  • docs: changes that affect the documentation only
  • feat: a new feature
  • fix: a bug fix
  • perf: a code change that improves performance
  • refactor: a code change that neither fixes a bug nor adds a feature
  • revert: revert changes
  • style: changes that do not affect the meaning of the code (lint issues)
  • test: adding missing tests or correcting existing tests

Use the optional [ breaking ] keyword to declare a BREAKING CHANGE.

Examples

  • Commit message with description and breaking change in body
feat: allow provided config object to extend other configs [ breaking ] (closes #12)
  • Commit message with no body
docs: correct spelling in the contributing.md file
  • Commit message for a fix using an issue number.
fix: fix minor issue in code (closes #12)

Versioning guidelines

We rely on Semantic Versioning for versioning a release. Indeed, given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make a major evolution leading to breaking changes,
  • MINOR version when you add functionality in a backwards-compatible manner
  • PATCH version when you make backwards-compatible bug fixes.

The command yarn release:<type>, where <type> is either patch, minor or major, helps you to do the release.

It performs the following task for you:

  • increase the package version number in the package.json file
  • generate the change log
  • create a tag accordingly in the git repository and push it

TIP

Please refer to the Publish your app guide to learn more about the way to publish the modules and the applications

Contributor Code of Conduct

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

This Code of Conduct is adapted from the Contributor Covenant, version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/

- + \ No newline at end of file diff --git a/about/introduction.html b/about/introduction.html index d56f31689..c62e5a713 100644 --- a/about/introduction.html +++ b/about/introduction.html @@ -43,7 +43,7 @@
Skip to content

About

The Kalisio Development Kit (KDK) aims to simplify the development of geospatial web applications running on desktop or mobile devices. It is a strongly opiniated stack initially developed to build multitenancy applications provided as SaaS (i.e. Cloud) like Kalisio Crisis. However, you can also build legacy applications because of the modularity and the flexibility of the KDK.

Kano application built with the KDK

Our objective is to propose a microservice based platform. Each building block has the responsibility to deliver specific and limited functionalities. Such an architectural approach plays a key role in helping us face the challenge of maintaining several mature products that need scalability within multiple contexts in terms of processing, storage, and features delivery.

If you'd like more information on how this documentation is built please refer to our tools section.

- + \ No newline at end of file diff --git a/about/license.html b/about/license.html index 4f023e76a..53b1fe742 100644 --- a/about/license.html +++ b/about/license.html @@ -43,7 +43,7 @@
Skip to content

License

MIT License

Copyright (c) 2017-20xx Kalisio

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

- + \ No newline at end of file diff --git a/about/roadmap.html b/about/roadmap.html index b8d71f20d..8eb872726 100644 --- a/about/roadmap.html +++ b/about/roadmap.html @@ -43,7 +43,7 @@
Skip to content

Roadmap

The roadmap is available on Github.

Release Notes

Release Notes for each modules are available on Github:

The changelogs are available on Github

- + \ No newline at end of file diff --git a/api/core/application.html b/api/core/application.html index 989a0cc50..7833377d6 100644 --- a/api/core/application.html +++ b/api/core/application.html @@ -183,7 +183,7 @@ } this.showError(error.message) }) - + \ No newline at end of file diff --git a/api/core/components.html b/api/core/components.html index c126cf5d3..56e357335 100644 --- a/api/core/components.html +++ b/api/core/components.html @@ -88,7 +88,7 @@ 'create': { name: 'create-group', component: 'editor/KModalEditor', props: true }, 'edit/:objectId': { name: 'edit-group', component: 'editor/KModalEditor', props: true } }

The properties to declare a k-modal-editor are identical to those of the k-modal-editor plus:

Chart

The KDK provides a helper component that allows rendering charts based on chart.js.

In addition and only if needed, it uses chroma.js to provide the backgoundColor array in order to render the different datasets of the chart. You can provide the color scale of your choice by setting the scaleColor property on each datasets.

Checkout the ChartActivity to understand how it works.

TIP

Have a look at the choma color scales to see how to define your color scale.

Authentication

The KDK provides you with some default forms to manage login, logout, registration and server endpoint configuration for mobile apps in the authentication folder.

User Account

The KDK provides you with a default activity to manage user accounts in the account folder:

- + \ No newline at end of file diff --git a/api/core/composables.html b/api/core/composables.html index 4418bd4bd..f3dfcbf0b 100644 --- a/api/core/composables.html +++ b/api/core/composables.html @@ -43,7 +43,7 @@
Skip to content

Composables

useStore

Used to setup a reactive store, call useStore() with the following arguments:

  • name unique store name within the application
  • initialStore initial store content if any

The composable exposes the following:

  • store: the created store object
  • clear(): reset store content
  • set(path, value): set a store value by path
  • get(path): get a store value by path
  • unset(path): unset a store value by path
  • has(path): test if a store has a value by path
  • forOwn(f): call function f on each (value, key) of the store

useSelection

Used to setup a reactive store for selection items, call useSelection() with the following arguments:

  • name unique store name within the application
  • options options to setup the store
    • matches comparison function to identify two selected items as equal, defaults to Lodash matches

The composable exposes the following:

  • selection: the created store object
  • clearSelection(): reset selection content
  • get/setSelectionMode(mode): get current selection mode or switch between 'single' or 'multiple' mode
  • get/setSelectionFilter(filter): get/set filtering function to avoid selecting certain items
  • selectItem(path): select a new item
  • unselectItem(path): unselect an item
  • has/getSelectedItem(), has/getSelectedItems(): check for selected item(s) depending on selection mode

Activity

useActivity

Used to setup states and options for a new activity, call useActivity() with the following arguments:

  • name unique activity name within the application
  • options options to setup the activity
    • selection true to also create a selection store associated with the activity
    • state initial state content if any

Causes the current activity to be automatically reset on unmount.

The composable exposes the following:

  • state: the store object for activity state
  • options: the store object for activity options
  • setCurrentActivity(activity): set the given component as the current activity
  • elements exposed by the selection composable associated to the activity

useCurrentActivity

Used to access the current activity, call useCurrentActivity() with the following arguments:

  • options options to retrieve the activity
    • selection true to also retrieve the selection store associated with the activity
    • state initial state content if any

Causes the current activity to be automatically reset on unmount.

The composable exposes the following:

  • state: the store object for current activity state
  • options: the store object for current activity options
  • elements exposed by the selection composable associated to the activity
- + \ No newline at end of file diff --git a/api/core/hooks.html b/api/core/hooks.html index c870264d9..5451b09f8 100644 --- a/api/core/hooks.html +++ b/api/core/hooks.html @@ -49,7 +49,7 @@ service.hooks({ before: { all: [ hooks.convertObjectIDs(['participant', 'event']) ] } })

convertDates(properties, asMoment)

Return a hook function according to provided property list and Date/moment object flag

Transform a known set of properties from strings into a Data or moment object on client queries.

Fields are searched on hook.data or hook.params.query

js
import { hooks } from '@kalisio/kdk/core.api'
 // Will convert data.expireAt to Date
 service.hooks({ before: { create: [ hooks.convertDates(['expireAt']) ] } })

setAsDeleted(hook)

Flag the item as deleted when required by subsequent operations.

Delete flag is stored in the deleted field

populatePreviousObject(hook)

To be used a a before hook

Retrieve the target object before an update or a patch operation.

Previous object is stored in hook.params.previousItem

setExpireAfter(delayInSeconds)

To be used a a before hook Return a hook function according to provided delay

Set the MongoDB TTL on the target object.

TTL is stored in the expireAt field

Service

rateLimit(options)

To be used a before hook Return a hook function according to provided options

Rate limit the call of a target service (and possibly operation) according to the following options:

Rely on the token bucket algorithm

Authorisations

populateSubjects(hook)

Retrieve the target subject object(s) for an authorisation operation.

Specialises populateObjects with the following options:

populateResource(hook)

Retrieve the target resource object for an authorisation operation.

Specialises the populateObject with the following options:

authorise(hook)

Usually used as a app-level hook

Check permissions to access target resource object(s) for current user on the performed operation.

If the operation is authorised the hook.params.authorised flag will be set to true.

If you'd like to force/unforce authorisation check use the hook.params.checkAuthorisation flag.

By default check will only be performed when called from a client not from the server itself.

updateAbilities(options)

Return a hook function according to provided options

Update cached subject abilities when permissions have changed according to the following options:

Users

enforcePasswordPolicy(options)

To be used a before hook Return a hook function according to provided options

Check password policy when creating/updating the user's password according to the following options:

For more information read about password policy configuration.

storePreviousPassword(options)

To be used a before hook Return a hook function according to provided options

Update the password history when updating the user's password according to the following options:

For more information read about password policy configuration.

generatePassword(hook)

To be used a before hook

Generate a random password according to password policy (if any) and store it in the password item field.

For more information read about password policy configuration.

Organisations

createOrganisationServices(hook)

To be used an after hook

Create the database used to store organisation data and registered organisation services. Hook result is expected to be the organisation object and the organisation ID will be used as the database name.

removeOrganisationServices(hook)

To be used an after hook

Delete the database used to store organisation data and registered organisation services. Hook result is expected to be the organisation object.

createOrganisationAuthorisations(hook)

To be used an after hook

Set default membership of the user as params to organisation owner after creating it. Hook result is expected to be the organisation object.

removeOrganisationAuthorisations(hook)

To be used an after hook

Removes membership of all users of the organisation after removing it. Hook result is expected to be the organisation object.

Groups

createGroupAuthorisations(hook)

To be used an after hook

Set default membership of the user as params to group owner after creating it. Hook result is expected to be the group object.

removeGroupAuthorisations(hook)

To be used an after hook

Removes membership of all users of the group after removing it. Hook result is expected to be the group object.

Logs

log(hook)

Usually used as a app-level hook

Events

emit(hook)

Usually used as a app-level hook

Emit an event named {hook_type}Hook (e.g. beforeHook or afterHook) for each hook ran, the payload of the event being the hook object.

- + \ No newline at end of file diff --git a/api/core/introduction.html b/api/core/introduction.html index 997b44ae2..faed784fb 100644 --- a/api/core/introduction.html +++ b/api/core/introduction.html @@ -52,7 +52,7 @@ Layout.bindContent([{ id: 'action', icon: 'las la-eye-dropper', label: 'MyActivity.ACTION_LABEL', handler: 'onAction' }], myComponent) - + \ No newline at end of file diff --git a/api/core/mixins.html b/api/core/mixins.html index b6a1a90ab..9e23c41f1 100644 --- a/api/core/mixins.html +++ b/api/core/mixins.html @@ -43,7 +43,7 @@
Skip to content

Mixins

Authentication

Provide basic methods to register(user), login(email, password), logout(), and restoreSession().

Will make the currently authenticated user available in the user property of the global store.

Authorisation

Compute user' abilities and keeps it up-to-date on user' permissions changes.

Abilities are stored in the user.abilities property of the global store.

Base Activity

Make it easier to update the application layout when the user changes his current activity:

  • clearTitle()/setTitle() (un)sets the application bar title in store appBar property
  • clearActions()/registerAction(type, action) (un)registers actions to be used by the activity
    • registerFabAction() registers actions to be used in action button, type = 'fab'
    • registerTabAction() registers actions to be used in navigation bar, type = 'tabBar'
  • clear/setSearchBar(field, services) (un)sets the application search bar in store searchBar property
  • clear/setLeftDrawer(component, content) (un)sets the application left drawer in store leftDrawer property
  • clear/setRightDrawer(component, content) (un)sets the application right drawer in store rightDrawer property
  • clearActivity() resets actions/title used by the activity
  • refreshActivity() should be overridden in concrete activities to implement action registration and title - search bar - right panel setup

Causes the activity to be automatically refreshed on user' permissions changes or route change.

Base Collection

Used to retrieve items from a specific service and keep track of real-time updates using RxJS:

  • (un)subscribe() causes the component to (un)subscribe to real-time events
  • refreshCollection() queries the service to retrieve items according to current pagination settings
  • getCollectionBaseQuery() should be overridden in concrete activities to implement any required parameter in the base query
  • getCollectionFilterQuery() should be overridden in concrete activities to provide any filtering parameter

To be used with the service mixin.

Base Item

Make it easier to setup items displayed by a collection:

  • clearActions()/registerAction(type, action) (un)registers actions to be used on the item
    • registerPaneAction() registers actions to be used in item pane, type = 'pane'
    • registerMenuAction() registers actions to be used in item menu, type = 'menu'
  • refreshActions() should be overridden in concrete items to implement action registration

Causes the item actions to be automatically refreshed on user' permissions changes.

Base Context

Retrieve the current context of the application from the contextId props, usually set on the target route:

  • clearContext() clears actions set by the context and context in store
  • refreshContext() clears the current context if contextId is not set or retrieve it if different from current one
  • getActionsForContext() can be overridden in concrete context-aware components to provide actions required by the context to be set it in the application bar, default behavior is to get the action list from the configuration context.actions property.

The context service to be used is the one set in the context.service property of the configuration.

Causes the context to be automatically refreshed on route change.

Will make the context available in the context property of the global store.

Service Proxy

Make it easier to access an underlying service from the contextId and service props:

  • getService() to retrieve the service

Object Proxy

Make it easier to access an underlying object of a given service from the objectId and perspective props:

  • getObject() to retrieve the service object
  • getObjectId() to retrieve the service object ID
  • loadObject() causes the service object to be resolved for current properties values

TIP

If a perspective is configured only that perspective will be retrieved.

DANGER

The service mixin is mandatory when using this mixin.

Schema Proxy

Make it easier to access an underlying JSON schema object for a given service from the schema-name, service or schema-json props:

  • getSchema() to retrieve the schema object
  • getSchemaId() to retrieve the schema object ID
  • getSchemaName() to retrieve the schema name
  • loadSchema() causes the schema object to be resolved for current properties values

If a JSON schema is directly provided (as a string) it will be parsed, otherwise it will load a schema file which name is computed like this:

  • basename is the given schema name or service name
  • suffix is .update if the objectId props is defined or .create otherwise
  • -perspective is added to suffix if the perspective props is defined
  • extension is always .json

WARNING

This mixin has been designed to be used with the service mixin and the object mixin.

For instance, if you set props like this <my-editor service="users"/> on your component using the mixins, the users.create.json schema file will be loaded. If you set props like this <my-editor service="users" :objectId="objectId" perspective="profile"/>, the users.update-profile.json schema file will be loaded.

Base Editor

Make it easier to build editors from baseObject and baseQuery props, as well as props defined on associated mixins:

  • getMode() returns updated or create depending if the objectId props is defined or not
  • fillEditor() fill all forms with current object values
  • clear() clear all forms back to default values
  • validateForms() validate all forms
  • applyForms() call apply() on all forms
  • submittedForms() call submitted() on all forms
  • getBaseObject() return retrieved object from service or input base object as defined in baseObject props, if a perspective is defined through the perspective props only that perspective is returned.
  • getBaseQuery() return input base query as defined in baseQuery props, will automatically add object ID and perspective to query if any defined
  • async apply(event, done) setups all the underlying objects to make it ready for edition
  • refresh() setups all the underlying objects to make it ready for edition
    1. load service from the contextId and service props
    2. load schema from the schema-name, service or schema-json props
    3. load object from the objectId and perspective props
    4. load form refs from the set of refs that have been defined
    5. build forms
    6. fill forms

DANGER

This mixin has been designed to be used with the service mixin, the schema mixin, the object mixin and the refs resolver mixin.

TIP

The baseObject props is usually used to keep track of existing or additional "hidden" or "internal" properties in addition to the ones edited throught the form.

Check out a code example here to see how to create your own editors.

Base Field

Make it easier to build form fields from the properties and display props:

  • emptyModel() get the default "empty" value of the field, returns an empty string by default
  • clear() set the current value of the field to be the default one if provided through properties.field.default, use "empty" model value otherwise
  • value() get the current value of the field, simply gets the value from model by default
  • fill(value) set the current value of the field, simply copies the value as model by default
  • apply (object, field) applies the current field value on the given target object, simply copies the value in the object by default, to be overloaded if you need to perform specific operations before the form has been submitted
  • submitted (object, field) does nothing by default, to be overloaded if you need to perform specific operations after the form has been submitted
  • onChanged() emits the field-changed event whenever the field value has changed, consequently the form will validate or invalidate the field, should be binded in template to events like blur.

Quasar field components are usually used to implement form fields, the given set of computed properties are available to be bound:

  • icon alias for properties.field.icon if display.icon is true, empty by default
  • label alias for properties.field.label if display.label is true, empty by default
  • helper alias for properties.field.helper
  • disabled alias for properties.field.disabled, false by default
  • hasError boolean indicating if a validation error has occured
  • errorLabel alias for properties.field.errorLabel, empty by default

TIP

label, helper and errorLabel properties will be automatically internationalized if corresponding values are valid translation keys.

Check out a code example here to see how to create your own fields.

Version

Make it easier to display information about client and API versions in applications:

  • refreshVersionNames() retrieves the version information, it will be stored in clientVersionName and apiVersionName data variables
- + \ No newline at end of file diff --git a/api/core/services.html b/api/core/services.html index dd45777ee..28d3416f0 100644 --- a/api/core/services.html +++ b/api/core/services.html @@ -96,7 +96,7 @@ }, "required": ["x"] } - + \ No newline at end of file diff --git a/api/introduction.html b/api/introduction.html index 4cd22ed88..adbd5bc4f 100644 --- a/api/introduction.html +++ b/api/introduction.html @@ -46,7 +46,7 @@ response.data.forEach(user => { // Do something with the current user })

Depending on the permissions set on the user by the application he might not have access to all items of the service.

The following table illustrates the correspondance between REST operations, service methods and real-time events:

Feathers Services

Hooks

KDK modules provide a collection of hooks to be used by modules or client applications. They often rely on Feathers common hooks.

Hooks are the main way to introduce business logic into applications and modules so we recommend to understand them well first before reading this.

Each service can include a set of internal hooks, i.e. hooks required to make the service work. They are built-in with the service and cannot usually be removed.

Each module then exposes a set of external hooks you can use to extend the capabilities of your application. They are not built-in with the services and are usually added or removed on-demand by your application. The main reason is that you must have control over the order of execution when mixing different hooks to best fit your application logic and avoid any side effect.

We try to organise hooks in different categories:

Others hooks are usually service-centric and so attached to the target service.

Data model

Each service can declare a set of perspectives, which are not retrieved by default when querying the object(s), you will need to use $select to do so. A perspective is simply a field of the data model containing a nested object, like the profile field containing the user's profile information on the user data model.

All dates/times in KDK are managed as date or moment objects and expressed in UTC.

Client

KDK modules provide a collection of reusable mixins and components to be used by modules or applications.

Mixins are a flexible way to distribute reusable functionalities for Vue components. A mixin object can contain any component options. When a component uses a mixin, all options in the mixin will be "mixed" into the component's own options.

Although .vue single file components are stored at the module level to ensure synchronized configuration management with backend code they are not "processed" within. Instead, the application processes them directly using WebPack dynamic imports.

WARNING

Single component files are temporarily copied into the application folder during the build process, in development mode they are directly imported from (linked) modules using hot reload.

Testing

You will find here a collection of ready-to-go REST requests to test the API with the great POSTMAN tool. Simply download it and import it in your POSTMAN installation.

You should do the following:

  1. make your application run (the collection is configured for default dev port 8080 but you can easily switch to 8081 for production mode for instance or any other)
  2. use the authenticate request with a registered user e-mail/password to retrieve an authorization token
  3. set this token in the header of other requests in order to be authorized to perform the request
  4. renew your token when expired (step 2)
- + \ No newline at end of file diff --git a/api/map/components.html b/api/map/components.html index 131ec162d..c4c20e3cf 100644 --- a/api/map/components.html +++ b/api/map/components.html @@ -116,7 +116,7 @@ } } ]

TIP

It is also possible to add your own type of legend. You must implement the component responsible of the rendering and register it to the KLegend through the renderers prop. The component must overload the abstract KLegendRenderer component.

- + \ No newline at end of file diff --git a/api/map/composables.html b/api/map/composables.html index 66ed6795e..7896f8209 100644 --- a/api/map/composables.html +++ b/api/map/composables.html @@ -43,7 +43,7 @@
Skip to content

Composables

useSelection

Used to setup a reactive store for selection features, similar to core selection composable with the following additional options:

  • options options to setup the store
    • multiple: key for multiple selection, defaults to 'ctrlKey'
    • buffer: buffer selection width, default to 10 pixels
    • boxSelection: flag to enalbe selection by bbox, defaults to true
    • clusterSelection: flag to enable selection of all fatures of a cluster when selecting a cluster, defaults to false

The composable exposes the following additional elements:

  • has/getSelectedLocation(): check/get the selected location if any (when not selecting a feature)
  • has/getSelectedLayer(): check/get the layer of selected features(s) if any
  • has/getSelectedFeature(), has/getSelectedFeatureCollection(): check for selected features(s) depending on selection mode
  • centerOnSelection(): center current view on selected items
  • getWidgetForSelection(): get widget corresponding to selected items, can be customized using the widget layer property, defaults to 'time-series' for layer with variables or 'information-box' otherwise

useProbe

Used to setup a reactive store for probing at a specific location, call useProbe() with the following arguments:

  • name unique store name within the application
  • options options to setup the store

The composable exposes the following:

  • probe: the created store object
  • clearProbe(): reset probing content
  • has/getProbedLocation(): check/get the selected probing location if any
  • has/getProbedLayer(): check/get the layer of selected probing location if any
  • probeAtLocation(): launch a probing action
  • centerOnProbe(): center current view on probed location
  • getWidgetForProbe(): get widget corresponding to probed location, defaults to 'time-series'

useHighlight

Used to setup a reactive store for storing highlights related to selected features, call useHighlight() with the following arguments:

  • name unique store name within the application
  • options options to setup the store
    • updateDelay: debounce delay to update highlight whenever selection changes
    • asBbox: flag to indicate if lines/polygons are highlighted using their respective bounding bonx; defaults to false
    • map style properties to customize highlight rendering

The composable exposes the following:

  • highlights: the created store object
  • clearHighlights(): reset highlight content
  • has/getHighlight(feature, layer): check/get a given highlight if any
  • highlight(feature, layer): highlight a new feature
  • unhighlight(feature, layer): unhighlight a feature

Under-the-hood, highlights are managed using a GeoJson layer.

useProject

Used to manage a map project, call useProject() with the following arguments:

  • route flag indicating if project should be extracted from route otherwise it should be loaded manually
  • context context ID for the project service
  • updateActivity: defaults to true
  • planetApi: target api object

Watches route change to track project ID

The composable exposes the following:

  • project: the current project object
  • projectId: the ID of the project to be loaded
  • hasProject(): check if a project to be loaded is specified
  • isProjectLoaded(): check if current project is loaded
  • loadProject(): load project if any specified
  • catalogProjectQuery: get query to retrieve layers from catalog for current project

Activity

useActivity

Used to setup states and options for a new activity, similar to core activity composable with the following additional options:

  • name unique activity name within the application
  • options options to setup the activity
    • probe true to also create a probe store associated with the activity
    • highlight true to also create a highlight store associated with the activity

The composable exposes the following additional elements:

useCurrentActivity

Used to access the current activity, similar to core activity composable with the following additional options:

  • options options to retrieve the activity
    • probe true to also retrieve the probe store associated with the activity
    • highlight true to also retrieve the highlight store associated with the activity

The composable exposes the following additional elements:

  • get/setActivityProject(): get or switch the current project used by the current activity
- + \ No newline at end of file diff --git a/api/map/globe-mixins.html b/api/map/globe-mixins.html index 9e26b2792..2b34ee74b 100644 --- a/api/map/globe-mixins.html +++ b/api/map/globe-mixins.html @@ -99,7 +99,7 @@ geometry: { type: 'LineString', coordinates: [...] } }] }

File Layer

Make it possible to drag'n'drop GeoJson or KML file on the globe. It will automatically create a new GeoJson layer named after the filename on drop. As a consequence it has to be used with the GeoJson layer mixin and will use the configured styling.

Globe Activity

Make it easier to create 3D mapping activities:

DANGER

It assumes that the DOM element used by the render engine has a ref named globe

- + \ No newline at end of file diff --git a/api/map/hooks.html b/api/map/hooks.html index bc737a787..35f33dc2a 100644 --- a/api/map/hooks.html +++ b/api/map/hooks.html @@ -43,7 +43,7 @@
Skip to content

Hooks

Query

asGeoJson(options)

Return a hook function according to provided options

Transform the hook results into a GeoJson object:

  • force: set to true to perform transformation whatever hook parameters, otherwise this hook will only be run when hook.params.asGeoJson is true (default)
  • longitudeProperty: name of the field where to read the longitude on result items
  • latitudeProperty: name of the field where to read the latitude on result items
  • altitudeProperty: name of the field where to read the altitude on result items
  • pick: an array of properties to be picked on result items using Lodash
  • omit: an array of properties to be omitted on result items using Lodash
  • properties: a map between input key path and output key path supporting dot notation, a value of the map is a structure like this:
    • from: input key path
    • to: output key path (defaults to input path if not given)
    • delete: boolean indicating if the input key path should be deleted or not after mapping
  • asFeatureCollection: true to output a GeoJson feature collection (default) otherwise will generate an array of GeoJson features

marshallSpatialQuery(hook)

Converts from client/server side spatial types (e.g. coordinates or numbers) to basic JS types, which is usually required when querying the database. Applies to MongoDB geospatial operators. It also manages shortcuts to create spatial queries for features in a given area.

Also set hook.params.asGeoJson to true when hook.query.geoJson is true (see above).

aggregateFeaturesQuery(hook)

Constructs query for feature aggregation over time.

Reads the query object to process from hook.params.query.$aggregate

- + \ No newline at end of file diff --git a/api/map/introduction.html b/api/map/introduction.html index a3f6f9bc2..394e884c4 100644 --- a/api/map/introduction.html +++ b/api/map/introduction.html @@ -78,7 +78,7 @@ // Launch a geolocation await Geolocation.update() const position = this.$store.get('geolocation.position') - + \ No newline at end of file diff --git a/api/map/map-mixins.html b/api/map/map-mixins.html index a127759cb..c65b2090b 100644 --- a/api/map/map-mixins.html +++ b/api/map/map-mixins.html @@ -35,7 +35,7 @@ - + @@ -50,7 +50,78 @@ minZoom: 7, maxZoom: 14 }] -}

Map Style

Make it possible to generate Leaflet map objects with style based on (Geo)Json (feature) properties:

Use register/unregisterStyle(type, generator) to (un)register a function generating a Leaflet object depending on the given type:

TIP

The simple style spec options does not cover all Leaflet style options. However you can use it simply by converting option names from camel case to kebab case.

Our mapping extends the simple style spec and can be used to create styles more easily:

The mixin automatically registers defaults styling:

Map Popup

Make it possible to generate Leaflet popups based on GeoJson feature properties. Use register/unregisterStyle(popup, generator) to (un)register a function f(feature, layer, options) returning a Leaflet popup

The mixin automatically registers a default generator that will create a popup displaying a property name/value table based on the following options with the following order of precedence

TIP

If you want to disable a default popup configuration like popup: { } (i.e. display all properties) on a per-layer basis you have to explicitely unset it on your layer options using popup: null or popup: false.

Map Tooltip

Make it possible to generate Leaflet tooltips based on GeoJson feature properties. Use register/unregisterStyle(tooltip, generator) to (un)register a function f(feature, layer, options) returning a Leaflet tooltip

The mixin automatically registers a default generator that will create a tooltip based on the following options with the following order of precedence

TIP

If you want to disable a default tooltip configuration like tooltip: { property: 'name' } (i.e. display all properties) on a per-layer basis you have to explicitely unset it on your layer options using tooltip: null or tooltip: false.

GeoJson Layer

Make it possible to manage and style raw or time-based GeoJson map layers (Leaflet.Realtime plugin is used under-the-hood):

DANGER

The style mixin is mandatory when using this mixin. If you'd like to support popups/tooltips you should also use the popup mixin and/or tooltip mixin.

If your component has a onLeafletFeature(feature, layer, options) method it will be called each time a new GeoJson feature is created.

Clustering

Marker clustering options are to be provided in the cluster property of the Leaflet layer options or in the cluster property of component options, with this order of precedence. The following configuration illustrates a GeoJson marker cluster layer using options set on the layer descriptor (see image below):

js
{
+}

Map Style

KDK intoduces its own stye specification as described as below:

js
style: {
+  // Line geometry
+  line: {
+    color: 'black' // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+    width:  1 // any positive value
+    opacity: 1.0 // range from 0.0 (transparent) to 1.0 (opaque)
+    cap: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
+    join: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
+    dashArray: 'none', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
+    dashOffset: 0 // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
+  },
+  // Polygon geometry
+  polygon: {
+    color: 'black', // fill color, any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+    opacity: 1.0, // fill opacity
+    fillRule: 'evenodd' // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule
+    stroke: {
+        color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+        width: 1, // any positive value
+        opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+        cap: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
+        join: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
+        dashArray: 'none', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
+        dashOffset: 0, // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
+    }
+  },
+  // Point geometry
+  marker: {
+    shape: 'circle', // represent a registered SVG shape
+    size: ['24px', '24px'], // array of HTML sizes
+    radius: undefined,  // alternative to the size property.
+    color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+    opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+    stroke: { 
+        color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+        width: 1, // any positive value
+        opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+        cap: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
+        join: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
+        dashArray: 'none', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
+        dashOffset: 0 // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
+    },
+    icon: {
+      classes: undefined // must be specified, e.g 'las la-home'
+      url: '' // url to the image to be displayed. Alternative to the classes property
+      color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+      opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+      size: '14px', // any HTML size
+      translation: ['-50%', '-50%'], // translation to apply to render the icon relative to the shape
+      rotation: 0 // rotation to apply to render the icon relative to the shape
+    },
+    text: {
+      label: undefined, // text to be displayed
+      color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+      size: '12px', // any HTML size
+      translation: ['-50%', '-50%'], // translation to apply to render the text relative to the shape
+      rotation: 0 // rotation to apply to render the text relative to the shape
+    },
+   html: null // an HTML element to be rendered
+  }
+}

KDK comes with a set of predefined marker shapes: circle, rect, rounded-rect, diamond, triangle, triangle-down, triangle-left, triangle-right, star, marker-pin, square-pin. But it allows you to register you own shape. For that, you have to define the shape such as below:

js
 'my-shape': {
+    content: // the SVG path of the shape (required)
+    viewBox: // the bounding box of the path (required)
+    icon: {
+      translation: // the default translation to apply to render the icon. Default value is ['-50%', '-50%'] (optional)
+    },
+    text: {
+      translation: // the default translation to apply to render the text. Default value is ['-50%', '-50%'] (optional)
+    },
+    anchor: 'bottom-center', // the anchor of the shape. Default value is `center-center` (optional)
+    radiusToSize: (r) => { return ...  } // a function to compute the size according a radius. Default function returns the double of the radius (optional)
+  },

In addition and for backward compatibility, KDK supports an enhanced simple style spec options with the following mapping:

SimpleStyleSpecKDK Style
z-indexpane
panepane
strokecolor
stroke-colorcolor
stroke-opacityopacity
stroke-widthweight
fillfillColor
fill-opacityfillOpacity
fill-colorfillColor
weightweight
radiusradius
line-caplineCap
line-joinlineJoin
dash-arraydashArray
dash-offsetdashOffset
marker-symbolstyle.point.shape
marker-sizestyle.point.size
marker-colorstyle.point.color
marker-anchorstyle.point.anchor
icon-urlstyle.point.icon.url
icon-htmlstyle.point.html
icon-colorstyle.point.icon.color
icon-sizestyle.point.icon.size
icon-anchorstyle.point.anchor
icon-classstyle.point.icon.classes
icon-opacitystyle.point.icon.opacity
icon-classesstyle.point.icon.classes
icon-x-offsetstyle.point.icon.xOffset
icon-y-offsetstyle.point.icon.yOffset

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset

The mixin automatically registers defaults styling for the the following type: point, line and polygon. For each type, the following options are merged with the following order of precedence: * feature style : feature.style or on simple style spec options feature.properties * layer style set on layer descriptor * engline style set on engine descriptot

Map Popup

Make it possible to generate Leaflet popups based on GeoJson feature properties. Use register/unregisterStyle(popup, generator) to (un)register a function f(feature, layer, options) returning a Leaflet popup

The mixin automatically registers a default generator that will create a popup displaying a property name/value table based on the following options with the following order of precedence

TIP

If you want to disable a default popup configuration like popup: { } (i.e. display all properties) on a per-layer basis you have to explicitely unset it on your layer options using popup: null or popup: false.

Map Tooltip

Make it possible to generate Leaflet tooltips based on GeoJson feature properties. Use register/unregisterStyle(tooltip, generator) to (un)register a function f(feature, layer, options) returning a Leaflet tooltip

The mixin automatically registers a default generator that will create a tooltip based on the following options with the following order of precedence

TIP

If you want to disable a default tooltip configuration like tooltip: { property: 'name' } (i.e. display all properties) on a per-layer basis you have to explicitely unset it on your layer options using tooltip: null or tooltip: false.

GeoJson Layer

Make it possible to manage and style raw or time-based GeoJson map layers (Leaflet.Realtime plugin is used under-the-hood):

DANGER

The style mixin is mandatory when using this mixin. If you'd like to support popups/tooltips you should also use the popup mixin and/or tooltip mixin.

If your component has a onLeafletFeature(feature, layer, options) method it will be called each time a new GeoJson feature is created.

Clustering

Marker clustering options are to be provided in the cluster property of the Leaflet layer options or in the cluster property of component options, with this order of precedence. The following configuration illustrates a GeoJson marker cluster layer using options set on the layer descriptor (see image below):

js
{
   name: 'Layer',
   description: 'My sites',
   tags: [ 'business' ],
@@ -115,7 +186,7 @@
     ]
   }
 }

The ctx object is the draw context and is the only object available from the draw code.

By default, the following fields are available on the draw context :

TIP

It is possible to extend what's available in the draw context from the application using the CanvasDrawContext singleton. In this case you should call CanvasDrawContext.merge(contextAdditionObject) to merge the content of contextAdditionObject with the draw context. This call must be done before the canvas layer mixin is created. This can be useful to build an application specific library of draw functions and make these available to the canvas layer instances.

Map Activity

Make it easier to create 2D mapping activities:

DANGER

It assumes that the DOM element used by the render engine has a ref named map

- + \ No newline at end of file diff --git a/api/map/mixins.html b/api/map/mixins.html index c67a24ba3..a48837ced 100644 --- a/api/map/mixins.html +++ b/api/map/mixins.html @@ -77,7 +77,7 @@ values: [ -10, -8, 0, 4, 9 ] */ }

The mixin adds the following functions:

This mixin also adds the following internal data properties:

- + \ No newline at end of file diff --git a/api/map/services.html b/api/map/services.html index ef65f92de..2036de9f7 100644 --- a/api/map/services.html +++ b/api/map/services.html @@ -193,7 +193,7 @@ } }) // Do something with the resulting feature collection

Real-time events

Individual events are emitted as usual by default. However, as the features service might be used to import/export a lot of features by batch, multiple operations will only emit a single event with the affected bounding box (bbox field), time range (startTime, endTime fields) and list of layers (layers field). Moreover, result of such operations will only contain the _id of the features not the whole object. You can control this behaviour with the following service options:

TIP

You can always force event or full result emission with the emitEvents/fullResult query parameters.

Hooks

The following hooks are executed on the features service:

null

These are mainly hooks to convert from/to JS/MongoDB data types.

Projects service

TIP

Available as a global and a contextual service

The service can be created using the global createProjectsService(options) function, if no context provided it will be available as a global service otherwise as a contextual service (e.g. attached to a specific organization), please also refer to core module createService().

Data model

A project consists in a set of map layers and contexts taken from the whole catalog.

The data model of a project as used by the API is the following:

Hooks

The main hooks executed on the projects service are used to convert from/to JS/MongoDB data types:

Additional hooks are run to populate layers/context with more information like name and underlying service when using the populate query paramter.

Alerts service

TIP

Available as a global and a contextual service

The service can be created using the global createAlertsService(options) function, if no context provided it will be available as a global service otherwise as a contextual service (e.g. attached to a specific organization), please also refer to core module createService().

WARNING

update method is not allowed now, you have to recreate the alert if you'd like to update it. patch method is only allowed from the server side in order to update the alert status.

Alerts are user-defined conditions automatically and continuously evaluated as new time-based data are gathered and target sensor measures or forecast data. It can be viewed as an automated query of the feature aggregation API or Weacast probe API that will raise an event or trigger a webhook whenever a matching result is found. With alerts you can create triggers which will fire on an occurrence of the selected measure or weather conditions (temperature, humidity, pressure, etc.) in a specified location and period of time.

Data model

The common model is a GeoJSON feature with the geometry of the source feature for measurements or a GeoJSON point for weather.

The data model of an alert as used by the API is detailed below.

Alert data model

The details of some of the properties are the following:

Hooks

The following hooks are executed on the alerts service:

null

These are mainly hooks to convert from/to JS/MongoDB data types.

- + \ No newline at end of file diff --git a/architecture/component-view.html b/architecture/component-view.html index 46d6d5520..db872a3a9 100644 --- a/architecture/component-view.html +++ b/architecture/component-view.html @@ -43,7 +43,7 @@
Skip to content

Component view

The typical components and the underlying dependencies of KDK are summarized in the following diagram.

Component view

- + \ No newline at end of file diff --git a/architecture/data-model-view.html b/architecture/data-model-view.html index e5a13db0b..64a3ab833 100644 --- a/architecture/data-model-view.html +++ b/architecture/data-model-view.html @@ -43,7 +43,7 @@
Skip to content

Data model-oriented view of the architecture

According to the Feathers philosophy each data model is manipulated using a service interface to perform CRUD operations of the persistence layer. So this data model-oriented view is a service-oriented view in the same manner.

Because data models internally rely on JSON they are by nature hierarchical. In the following diagrams each nested JSON object is represented as a smaller bubble in a bigger bubble (the nesting/parent object), the data model instance being the root JSON object or the biggest bubble. The name of the bubble is the name of the nesting object property owing the nested object.

Data models are dynamic by nature, allowing any plugin to add custom fields whenever required using hooks. Each data model includes an implicit ObjectID _id field provided by the database.

User data model

The most common properties of a user are described by the following data model:

User data model

The details of each property are the following:

  • email : user e-mail used as an internal unique ID
  • password : hashed user password
  • locale : user locale when registering
  • previousPasswords : hashed user password history if password policy has been enabled
  • profile : user profile information including name
  • [provider] : user profile information for associated OAuth provider, e.g. google
  • [scope] : user permissions for associated scope, e.g. groups
  • tags : user affected tags if any
  • subscriptions : user web push subscriptions if any

Subscription data model

As per feathers-webpush, subscriptions are attached to users through the subscriptions property.

Notification data model

As per feathers-webpush, notifications are sent according to subscriptions are attached to users.

This data model is manipulated through the push service.

Tag data model

The most common properties of a tag object are described by the following data model:

Tag data model

This data model is manipulated through the tag service.

The details of each property are the following:

  • scope: the scope of the tag (i.e. category), e.g. skill
  • value: the value of the tag, e.g. developer
  • icon: the icon specification for this tag if any
  • context: the ID of the associated context object providing this tag if any (e.g. the organisation)

Organization data model

The most common properties of an organization are described by the following data model:

Organization data model

This data model is manipulated through the organizations service.

The details of each property are the following:

  • name: the name of the organisation
  • description: the description of the organisation

the organization ObjectID is used as the internal DB name

Group data model

The most common properties of a group object are described by the following data model:

Group data model

This data model is manipulated through the groups service.

The details of each property are the following:

  • name: the name of the group
  • description: the description of the group
- + \ No newline at end of file diff --git a/architecture/global-architecture.html b/architecture/global-architecture.html index 50e636c83..89e6cd6e5 100644 --- a/architecture/global-architecture.html +++ b/architecture/global-architecture.html @@ -56,7 +56,7 @@ } } }

The above example will proxy the request /api/service/1 to http://my.service.com/api/1.

However, all of this requires manual work, creates a tight coupling with your underlying infrastructure and will not allow auto-scaling unless you have some discovery mechanism. You can make each instance automatically aware of others instances to distribute services and related events using feathers-distributed.

- + \ No newline at end of file diff --git a/architecture/introduction.html b/architecture/introduction.html index 3b6e9b2e5..5d6aa7f95 100644 --- a/architecture/introduction.html +++ b/architecture/introduction.html @@ -43,7 +43,7 @@
Skip to content

Architecture

Before jumping to the global architecture view we recommend to read about the main concepts of KDK.

You can then have a look to the:

  1. component-oriented view
  2. data model-oriented view
- + \ No newline at end of file diff --git a/architecture/main-concepts.html b/architecture/main-concepts.html index 538fb585a..a8cf9a4a3 100644 --- a/architecture/main-concepts.html +++ b/architecture/main-concepts.html @@ -43,7 +43,7 @@
Skip to content

Main concepts

WARNING

Although this page details the main data model used for SaaS applications the organisation part is optional and you can build legacy applications just by using services.

Services

According to the Feathers philosophy each business operation should be performed through a service interface. As a consequence, these are are the building blocks at the heart of each KDK application.

Organisation model

Organisations are the basic elements that permit to create and configure teams (i.e. groups of users) and invite others to join and share content. Organisations are shared workspaces where users can collaborate using a set of services only available within the context of the organisation.

Data segregation

KDK implements an extreme solution to segregate data at the source: using different databases. This means that dedicated databases (respectively services) are created to hold (respectively to manage) the contextual assets when organisations are made available, and simply destroyed when they are not anymore.

TIP

Under the hood the feathers-mongodb-management module is used to dynamically create/remove a database per organisation whenever required

Using the KDK you can dynamically declare services to access organisation assets stored in this segregated DB.

Permissions

Organisation owners can manage member access to an organisation with a pre-defined set of permissions based on Attribute Based Access Control (ABAC), which allows to enforce authorization decisions based on any attribute accessible to the application and not just the user's role. Similarly, resource owners can manage member access to a given resource (e.g. a group).

All permissions are stored along with the user so that they are always available once authenticated. They are organised by resource types (what we call scopes). The authorisation service allow to:

  1. add, respectively remove, a set of permissions (e.g. being a owner or a manager)
  2. for a subject (i.e. a user in most case but it could be generalized)
  3. on a resource (e.g. an organisation or a group).

TIP

Under the hood the CASL module is used to manage the permissions

Domain model

The domain model is a set of high-level abstractions that describes selected aspects of a sphere of activity, it is a representation of meaningful real-world concepts pertinent to the domain that are modeled in the software. The concepts include the data involved in the business and rules the business uses in relation to that data.

The class diagram used to represent the domain model in the Unified Modeling Language (UML) is presented afterwards. The Kalisio domain model is implemented as a hybridation between objects and cross-cutting concerns within a layer that uses a lower-level layer for persistence and publishes an API to a higher-level layer to gain access to the data and behavior of the model.

Domain model

To get into the details of this model look at the persisted data model and the provided API.

- + \ No newline at end of file diff --git a/assets/api_map_map-mixins.md.cLyjeJ2i.js b/assets/api_map_map-mixins.md.cLyjeJ2i.js new file mode 100644 index 000000000..034a62093 --- /dev/null +++ b/assets/api_map_map-mixins.md.cLyjeJ2i.js @@ -0,0 +1,144 @@ +import{_ as s,c as i,o as a,V as e}from"./chunks/framework.MC2QjGNi.js";const t="/kdk/assets/marker-cluster-2D.ys8JF8HW.png",y=JSON.parse('{"title":"Map Mixins","description":"","frontmatter":{},"headers":[],"relativePath":"api/map/map-mixins.md","filePath":"api/map/map-mixins.md"}'),n={name:"api/map/map-mixins.md"},l=e(`

Map Mixins

The underlying map object is based on Leaflet and some mixins also rely on Leaflet plugins. The following set of mixins is to be used to construct a new map activity and underlying Leaflet objects.

Base Map

DANGER

This mixin is a mandatory one to build a map activity

Make it possible to manage map layers and extend supported layer types:

This mixin also adds the following internal data properties:

This mixin automatically includes some Leaflet plugins: leaflet-fa-markers to create markers using Font Awesome icons, Leaflet.fullscreen to manage fullscreen mode, Leaflet.markercluster to create marker clusters, Leaflet.VectorGrid to display vector tiles.

Managing panes

Although DOM-based layers like Markers could make use of a z-index to possibly manage render order between them, SVG or canvas-based layers used to manage GeoJson features like Polylines provided no mean to do so. Similarly, there was no simple way to render some layers only at some specific zoom levels. This is the reason why Leaflet 1.0 introduced the concept of panes.

If you add a zIndex option to your layer descriptor we will create a dedicated pane for you under-the-hood so that the layer will be rendered at its right rank. Check the z-index value of the default panes to select the appropriate one.

If you add a panes option to your layer descriptor we will create the dedicated panes for you under-the-hood so that you can then set in the pane option of any sublayer the pane it will belong to. Each pane must have a unique name and can be visible at specific zoom levels:

js
{
+  name: 'Layer',
+  ...
+  panes: [{
+    name: 'waypoints',
+    minZoom: 7,
+    maxZoom: 14
+  }]
+}

Map Style

KDK intoduces its own stye specification as described as below:

js
style: {
+  // Line geometry
+  line: {
+    color: 'black' // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+    width:  1 // any positive value
+    opacity: 1.0 // range from 0.0 (transparent) to 1.0 (opaque)
+    cap: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
+    join: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
+    dashArray: 'none', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
+    dashOffset: 0 // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
+  },
+  // Polygon geometry
+  polygon: {
+    color: 'black', // fill color, any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+    opacity: 1.0, // fill opacity
+    fillRule: 'evenodd' // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule
+    stroke: {
+        color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+        width: 1, // any positive value
+        opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+        cap: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
+        join: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
+        dashArray: 'none', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
+        dashOffset: 0, // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
+    }
+  },
+  // Point geometry
+  marker: {
+    shape: 'circle', // represent a registered SVG shape
+    size: ['24px', '24px'], // array of HTML sizes
+    radius: undefined,  // alternative to the size property.
+    color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+    opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+    stroke: { 
+        color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+        width: 1, // any positive value
+        opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+        cap: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
+        join: 'round', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
+        dashArray: 'none', // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
+        dashOffset: 0 // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
+    },
+    icon: {
+      classes: undefined // must be specified, e.g 'las la-home'
+      url: '' // url to the image to be displayed. Alternative to the classes property
+      color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+      opacity: 1.0, // range from 0.0 (transparent) to 1.0 (opaque)
+      size: '14px', // any HTML size
+      translation: ['-50%', '-50%'], // translation to apply to render the icon relative to the shape
+      rotation: 0 // rotation to apply to render the icon relative to the shape
+    },
+    text: {
+      label: undefined, // text to be displayed
+      color: 'black', // any HTML color or [Quasar color](https://quasar.dev/style/color-palette/)
+      size: '12px', // any HTML size
+      translation: ['-50%', '-50%'], // translation to apply to render the text relative to the shape
+      rotation: 0 // rotation to apply to render the text relative to the shape
+    },
+   html: null // an HTML element to be rendered
+  }
+}

KDK comes with a set of predefined marker shapes: circle, rect, rounded-rect, diamond, triangle, triangle-down, triangle-left, triangle-right, star, marker-pin, square-pin. But it allows you to register you own shape. For that, you have to define the shape such as below:

js
 'my-shape': {
+    content: // the SVG path of the shape (required)
+    viewBox: // the bounding box of the path (required)
+    icon: {
+      translation: // the default translation to apply to render the icon. Default value is ['-50%', '-50%'] (optional)
+    },
+    text: {
+      translation: // the default translation to apply to render the text. Default value is ['-50%', '-50%'] (optional)
+    },
+    anchor: 'bottom-center', // the anchor of the shape. Default value is \`center-center\` (optional)
+    radiusToSize: (r) => { return ...  } // a function to compute the size according a radius. Default function returns the double of the radius (optional)
+  },

In addition and for backward compatibility, KDK supports an enhanced simple style spec options with the following mapping:

SimpleStyleSpecKDK Style
z-indexpane
panepane
strokecolor
stroke-colorcolor
stroke-opacityopacity
stroke-widthweight
fillfillColor
fill-opacityfillOpacity
fill-colorfillColor
weightweight
radiusradius
line-caplineCap
line-joinlineJoin
dash-arraydashArray
dash-offsetdashOffset
marker-symbolstyle.point.shape
marker-sizestyle.point.size
marker-colorstyle.point.color
marker-anchorstyle.point.anchor
icon-urlstyle.point.icon.url
icon-htmlstyle.point.html
icon-colorstyle.point.icon.color
icon-sizestyle.point.icon.size
icon-anchorstyle.point.anchor
icon-classstyle.point.icon.classes
icon-opacitystyle.point.icon.opacity
icon-classesstyle.point.icon.classes
icon-x-offsetstyle.point.icon.xOffset
icon-y-offsetstyle.point.icon.yOffset

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset

The mixin automatically registers defaults styling for the the following type: point, line and polygon. For each type, the following options are merged with the following order of precedence: * feature style : feature.style or on simple style spec options feature.properties * layer style set on layer descriptor * engline style set on engine descriptot

Map Popup

Make it possible to generate Leaflet popups based on GeoJson feature properties. Use register/unregisterStyle(popup, generator) to (un)register a function f(feature, layer, options) returning a Leaflet popup

The mixin automatically registers a default generator that will create a popup displaying a property name/value table based on the following options with the following order of precedence

TIP

If you want to disable a default popup configuration like popup: { } (i.e. display all properties) on a per-layer basis you have to explicitely unset it on your layer options using popup: null or popup: false.

Map Tooltip

Make it possible to generate Leaflet tooltips based on GeoJson feature properties. Use register/unregisterStyle(tooltip, generator) to (un)register a function f(feature, layer, options) returning a Leaflet tooltip

The mixin automatically registers a default generator that will create a tooltip based on the following options with the following order of precedence

TIP

If you want to disable a default tooltip configuration like tooltip: { property: 'name' } (i.e. display all properties) on a per-layer basis you have to explicitely unset it on your layer options using tooltip: null or tooltip: false.

GeoJson Layer

Make it possible to manage and style raw or time-based GeoJson map layers (Leaflet.Realtime plugin is used under-the-hood):

DANGER

The style mixin is mandatory when using this mixin. If you'd like to support popups/tooltips you should also use the popup mixin and/or tooltip mixin.

If your component has a onLeafletFeature(feature, layer, options) method it will be called each time a new GeoJson feature is created.

Clustering

Marker clustering options are to be provided in the cluster property of the Leaflet layer options or in the cluster property of component options, with this order of precedence. The following configuration illustrates a GeoJson marker cluster layer using options set on the layer descriptor (see image below):

js
{
+  name: 'Layer',
+  description: 'My sites',
+  tags: [ 'business' ],
+  icon: 'star',
+  attribution: '(c) My company',
+  type: 'OverlayLayer',
+  leaflet: {
+    type: 'geoJson',
+    source: 'https://s3.eu-central-1.amazonaws.com/kargo/nuclear-sites.json',
+    cluster: {},
+    'marker-color': 'orange',
+    'icon-color': 'white',
+    'icon-classes': 'fa fa-star',
+    popup: {
+      pick: [ 'NAME' ]
+    },
+    tooltip: {
+      property: 'LABEL'
+    }
+  }
+}

2D marker cluster

TIP

If you want to disable a default clustering configuration like cluster: { disableClusteringAtZoom: 18 } on a per-layer basis you have to explicitely unset it on your layer options using cluster: null or cluster: false.

Additional feature types

The following options can be set as feature properties to manage more geometry types:

Dynamic styling

Usually the same style is used for all features of a GeoJson layer, you might however require a more dynamic style base on each feature properties. To handle this use case you can either:

WARNING

Templating can only be efficient if compilers are created upfront, as a consequence you need to declare the list of templated options in your layer styling using the template property.

For instance you can change the marker color or image based on a given features's property like this:

js
'marker-color': \`<% if (properties.visibility < 75) { %>#000000<% }
+                  else if (properties.visibility < 300) { %>#d20200<% }
+                  else if (properties.visibility < 1500) { %>#f9b40f<% }
+                  else if (properties.visibility < 3000) { %>#eef52f<% }
+                  else { %>#33c137<% } %>\`,
+'marker-symbol': \`<% if (properties.visibility < 75) { %>/statics/windyblack.png<% }
+                    else if (properties.visibility < 300) { %>/statics/windyred.png<% }
+                    else if (properties.visibility < 1500) { %>/statics/windyorange.png<% }
+                    else if (properties.visibility < 3000) { %>/statics/windyyellow.png<% }
+                    else { %>/statics/windygreen.png<% } %>\`,
+template: ['marker-color', 'marker-symbol']

You can also draw a path with a different styling on each part like this:

js
{
+  type: 'FeatureCollection',
+  features: [{
+    type: 'Feature',
+    properties: { stroke: '#000000', weight: 1 },
+    geometry: { type: 'LineString', coordinates: [...] }
+  }, {
+    type: 'Feature',
+    properties: { stroke: '#FF00FF', weight: 3 },
+    geometry: { type: 'LineString', coordinates: [...] }
+  }]
+}

Edit Layer

Make it possible to edit features of a GeoJson layer (geometry and properties):

WARNING

It has to be used with the GeoJson layer mixin and will use the configured styling.

File Layer

Make it possible to drag'n'drop GeoJson or KML file on the map (Leaflet.FileLayer plugin is used under-the-hood). It will automatically create a new GeoJson layer named after the filename on drop. As a consequence it has to be used with the GeoJson layer mixin and will use the configured styling.

Forecast Layer

Make it possible to manage Weacast map layers:

WARNING

This mixin assumes that your component has initialized its Weacast client in the weacastApi property by using e.g. the Weacast mixin

Canvas Layer

Make it possible to draw custom graphic elements on top of other layers using HTML canvas elements. These custom graphic elements are defined by their draw function and are run in the client application, using a controlled draw context. It is not possible for these draw functions to access anything outside the specified context.

The following configuration illustrates a layer used to draw feature property name as text at the feature position for all features of the layer named Airports.

js
{
+  name: 'AirportNames',
+  type: 'OverlayLayer',
+  icon: 'local_airport',
+  leaflet: {
+    type: 'kanvasLayer',
+    isVisible: true,
+    draw: [
+      layer: 'Airports', code: \`
+        const props = ctx.feature.properties
+        const coords = {
+          lat: ctx.feature.geometry.coordinates[1],
+          lon: ctx.feature.geometry.coordinates[0]
+        }
+
+        const pos = ctx.latLonToCanvas(coords)
+        ctx.canvas.font = '10px sans-serif'
+        ctx.canvas.fillStyle = '#ffb300'
+        ctx.canvas.fillText(ctx.feature.properties.name, pos.x, pos.y)
+      \`
+    ]
+  }
+}

The ctx object is the draw context and is the only object available from the draw code.

By default, the following fields are available on the draw context :

TIP

It is possible to extend what's available in the draw context from the application using the CanvasDrawContext singleton. In this case you should call CanvasDrawContext.merge(contextAdditionObject) to merge the content of contextAdditionObject with the draw context. This call must be done before the canvas layer mixin is created. This can be useful to build an application specific library of draw functions and make these available to the canvas layer instances.

Map Activity

Make it easier to create 2D mapping activities:

DANGER

It assumes that the DOM element used by the render engine has a ref named map

`,77),r=[l];function p(o,h,k,d,c,g){return a(),i("div",null,r)}const u=s(n,[["render",p]]);export{y as __pageData,u as default}; diff --git a/assets/api_map_map-mixins.md.cLyjeJ2i.lean.js b/assets/api_map_map-mixins.md.cLyjeJ2i.lean.js new file mode 100644 index 000000000..70d165c32 --- /dev/null +++ b/assets/api_map_map-mixins.md.cLyjeJ2i.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,V as e}from"./chunks/framework.MC2QjGNi.js";const t="/kdk/assets/marker-cluster-2D.ys8JF8HW.png",y=JSON.parse('{"title":"Map Mixins","description":"","frontmatter":{},"headers":[],"relativePath":"api/map/map-mixins.md","filePath":"api/map/map-mixins.md"}'),n={name:"api/map/map-mixins.md"},l=e("",77),r=[l];function p(o,h,k,d,c,g){return a(),i("div",null,r)}const u=s(n,[["render",p]]);export{y as __pageData,u as default}; diff --git a/guides/basics/introduction.html b/guides/basics/introduction.html index 3592d3a40..e23bde885 100644 --- a/guides/basics/introduction.html +++ b/guides/basics/introduction.html @@ -43,7 +43,7 @@
Skip to content

Introduction to KDK

KDK is mainly powered by the following stack:

If you are not familiar with those technologies and want to develop with the KDK, we first recommend studying how they work. To get a deeper overview of some of the internals we also recommend you to read our technical articles on Medium:

Application template

A KDK-based application (a.k.a. skeleton) usually includes a front-end side client as well as back-end services or an API gateway proxying requests to back-end services. In order to ease the development of new applications we provide you with a KDK application template called the skeleton as a starting point. In this guide we will use the template as a reference when dealing with KDK-based application.

You can start your journey by running the skeleton.

KDK internals

Our main module is simply called kdk, available now as a single package @kalisio/kdk. It is actually composed of two logical parts:

  • core containing basic application services and components
  • map containing required services and components to build geospatial applications

TIP

Although bundled together you can only use the core part without the map part, for instance our application template does not use it. Indeed, on the bakend side related services will not be allocated if the map part is not explicitely used, and on the frontend side Webpack will not bundle unused components.

WARNING

The KDK was previously available as separated modules like kCore/@kalisio/kdk-core, kMap/@kalisio/kdk-map, etc. We strongly recommend to upgrade to the latest single package as the features remain similar and development is made easier.

The KDK relies on third-party modules which not directly integrated (they can be used as standalone modules), but it might be useful to know more about them. For instance:

As a consequence, we recommend reading this articles on Medium to get a deeper overview:

- + \ No newline at end of file diff --git a/guides/development/configure.html b/guides/development/configure.html index ac63a4c0e..7e72dcf89 100644 --- a/guides/development/configure.html +++ b/guides/development/configure.html @@ -43,7 +43,7 @@
Skip to content
- + \ No newline at end of file diff --git a/guides/development/deploy.html b/guides/development/deploy.html index c012bc79e..c87202e00 100644 --- a/guides/development/deploy.html +++ b/guides/development/deploy.html @@ -43,7 +43,7 @@
Skip to content
- + \ No newline at end of file diff --git a/guides/development/develop.html b/guides/development/develop.html index 52d5a2354..d7debfd1e 100644 --- a/guides/development/develop.html +++ b/guides/development/develop.html @@ -46,7 +46,7 @@ yarn install yarn link

Linting the code

The KDK relies on JavaScript standard style.

To lint the code:

bash
$yarn lint

You can also lint each of the submodules independently using the following commands:

bash
$yarn lint:core   # lint the core part
 $yarn lint:map    # lint the map part

:::

Web app

Please follow our application template development guide.

- + \ No newline at end of file diff --git a/guides/development/publish.html b/guides/development/publish.html index 97bc38fc3..8ee613e6b 100644 --- a/guides/development/publish.html +++ b/guides/development/publish.html @@ -43,7 +43,7 @@
Skip to content

Publish with KDK

The same process applies when releasing a patch, minor or major version of the KDK and third-party Kalisio modules, i.e. the following tasks are done automatically on release:

  1. increase the package version number in the package.json file (frontend and backend API)
  2. publish the module on the NPM registry
  3. create a tag accordingly in the git repository and push it

TIP

Kalisio maintained modules are published under the @kalisio namespace in NPM, e.g. kdk NPM package is named @kalisio/kdk, but you are free to use another one for your own modules.

WARNING

This requires you to have a NPM and GitHub account and be a team member of the namespace organization, if you'd like to become a maintainer of Kalisio maintained modules please tell us.

Depending on the release type the following command will do the job (where type is either patch, minor, major):

bash
npm run release:type

WARNING

Before you publish a module take care of updating the version of your dependent modules to the latest version published, for example perform yarn upgrade xxx for a module depending on the xxx module before publishing it

Web app

Almost the same process applies as for the modules except the app is not published on the NPM registry but in the Docker Hub. However, the process is less automated to ensure more flexibility so that the build artefacts of the different flavors can be managed independently.

Please follow our application template publishing guide.

- + \ No newline at end of file diff --git a/guides/development/setup.html b/guides/development/setup.html index f7e580138..5fc6e9a52 100644 --- a/guides/development/setup.html +++ b/guides/development/setup.html @@ -43,7 +43,7 @@
Skip to content

Setup your environment

Prerequisites

Install Node.js

Node is a server platform which runs JavaScript. It's lightweight and efficient. It has the largest ecosystem of open source libraries in the world.

WARNING

At the time of writing the KDK modules v2.x (master branch) are expected to work with Node.js 16.x and KDK modules v1.x are expected to work with Node.js 12.x

TIP

In order to be able to switch easily between different versions of Node.js we recommand to use a version manager like n/nvm under Linux/Mac or nvm under Windows.

Install Git

git is the version control system most frequently used in open source. There are many resources available for installing it.

TIP

Under Windows we recommand using Tortoise Git and to set the autocrlf flag in settings.

Install MongoDB

Mongo is an open-source, document database designed for ease of development and scaling.

WARNING

At the time of writing the KDK modules v2.x (master branch) are expected to work with MongoDB 4.x and KDK modules v1.x are expected to work with MongoDB 3.x

TIP

We recommand using Compass as a GUI for MongoDB, Robo 37 is also a good choice.

Install Yarn

Due to some changes in the way npm manages linked modules we prefer to use Yarn as a package manager.

Install Yarn on your platform.

Web app

Please follow our application template installation from source code guide.

- + \ No newline at end of file diff --git a/guides/development/test.html b/guides/development/test.html index fc7e6ca9f..977946849 100644 --- a/guides/development/test.html +++ b/guides/development/test.html @@ -44,7 +44,7 @@
Skip to content

Testing with KDK

The KDK relies on the Mocha testing framework and the Chai assertion library.

KDK and third-party Kalisio modules are Feathers modules, so you will find most of the required information in the linked Feathers documentation.

To run the module tests including linting and coverage : $ yarn test

To speed-up things simply run the tests with: $ yarn mocha

You can run the tests of each submodule independently using the following commands for the KDK:

bash
$yarn mocha:core   # test the core module
 $yarn mocha:map    # test the map module

TIP

If you need to perform some specific tests, you can use the -g or --grep option of the mocha command:

bash
$yarn mocha:core -g "core:team" # run the team tests

Web app

Please follow our application template testing guide.

- + \ No newline at end of file diff --git a/guides/introduction.html b/guides/introduction.html index 5303831b6..c2b9194b4 100644 --- a/guides/introduction.html +++ b/guides/introduction.html @@ -43,7 +43,7 @@
Skip to content

Guides

The Basics

The goal of this guide is to get you to the "A-ha!" moment as efficiently as possible. You will learn more about the underlying technological stack and how to deploy your first KDK app.

Development

In these guides you will learn step-by-step how the setup your development environment. You'll also learn how to create, develop and publish your own app and modules, which is also how we develop the KDK.

- + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json index 6cb346b37..8a562838f 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"api_core_introduction.md":"OHn0UJ2B","architecture_component-view.md":"R3doh1Va","api_map_composables.md":"kPf1FkcF","api_core_composables.md":"Jso_bCR-","api_map_components.md":"QfIkxMKt","api_map_globe-mixins.md":"tqOIx_mU","api_core_application.md":"AWFS2nBU","api_core_hooks.md":"xHdRnidf","api_core_mixins.md":"qkTTC_2T","about_introduction.md":"cLXaipnK","api_core_services.md":"udXHcl8C","about_contact.md":"tIYU1qZQ","api_core_components.md":"O_t3aKX6","about_roadmap.md":"1qI9rnCQ","about_license.md":"bCObHPkr","api_map_introduction.md":"DyWnjr1Q","architecture_data-model-view.md":"7n4In_kj","architecture_global-architecture.md":"wAOvZ27b","architecture_introduction.md":"rfkmVptE","architecture_main-concepts.md":"uF7n7Pb0","guides_basics_introduction.md":"aQ1SRmWM","guides_development_deploy.md":"17gOHDNG","guides_development_develop.md":"90BpPbED","guides_development_publish.md":"YYduP63e","guides_introduction.md":"Sb7FrAG3","index.md":"wR2UgPHC","tools_browsers.md":"HLLVqttH","guides_development_test.md":"Jo5v9Lze","guides_development_setup.md":"M_MgHAeh","about_contributing.md":"kNDvhZSW","api_map_map-mixins.md":"lvtUMtRu","tools_db.md":"f30L8wY9","guides_development_configure.md":"gtb3GRUD","tools_infrastructure.md":"L95k5suh","api_introduction.md":"WxS6S7yr","api_map_mixins.md":"jSNNAbuR","tips_introduction.md":"mIPxhkcg","api_map_hooks.md":"nHAqn2tp","tips_app-development.md":"Pl4LzVo1","tools_introduction.md":"CVHXlZ5c","tools_cli.md":"hHSUUSlV","tips_mobile-configuration.md":"HlKJ9Z8m","tools_documentation.md":"0d645ih4","api_map_services.md":"4x5W8ff9"} +{"guides_development_setup.md":"M_MgHAeh","api_core_mixins.md":"qkTTC_2T","about_roadmap.md":"1qI9rnCQ","tools_db.md":"f30L8wY9","about_contact.md":"tIYU1qZQ","api_core_introduction.md":"OHn0UJ2B","api_introduction.md":"WxS6S7yr","guides_development_test.md":"Jo5v9Lze","guides_development_configure.md":"gtb3GRUD","architecture_main-concepts.md":"uF7n7Pb0","index.md":"wR2UgPHC","guides_development_deploy.md":"17gOHDNG","api_core_services.md":"udXHcl8C","tools_cli.md":"hHSUUSlV","tips_introduction.md":"mIPxhkcg","tools_browsers.md":"HLLVqttH","about_license.md":"bCObHPkr","api_map_introduction.md":"DyWnjr1Q","tools_introduction.md":"CVHXlZ5c","tips_mobile-configuration.md":"HlKJ9Z8m","api_core_hooks.md":"xHdRnidf","architecture_introduction.md":"rfkmVptE","tools_documentation.md":"0d645ih4","guides_development_develop.md":"90BpPbED","architecture_global-architecture.md":"wAOvZ27b","api_map_globe-mixins.md":"tqOIx_mU","tools_infrastructure.md":"L95k5suh","about_introduction.md":"cLXaipnK","guides_introduction.md":"Sb7FrAG3","api_core_composables.md":"Jso_bCR-","api_map_composables.md":"kPf1FkcF","about_contributing.md":"kNDvhZSW","api_core_application.md":"AWFS2nBU","tips_app-development.md":"Pl4LzVo1","api_core_components.md":"O_t3aKX6","guides_development_publish.md":"YYduP63e","architecture_component-view.md":"R3doh1Va","guides_basics_introduction.md":"aQ1SRmWM","api_map_map-mixins.md":"cLyjeJ2i","api_map_hooks.md":"nHAqn2tp","api_map_services.md":"4x5W8ff9","api_map_components.md":"QfIkxMKt","api_map_mixins.md":"jSNNAbuR","architecture_data-model-view.md":"7n4In_kj"} diff --git a/index.html b/index.html index a97a6a724..dabad3756 100644 --- a/index.html +++ b/index.html @@ -43,7 +43,7 @@
Skip to content

KDK

The Kalisio Development Kit

kalisio-kdk
- + \ No newline at end of file diff --git a/tips/app-development.html b/tips/app-development.html index f7984d823..67d20c34b 100644 --- a/tips/app-development.html +++ b/tips/app-development.html @@ -65,7 +65,7 @@ // Monitor messages > SUBSCRIBE feathers-sync Reading messages... - + \ No newline at end of file diff --git a/tips/introduction.html b/tips/introduction.html index 6ad8be87f..6e6538d06 100644 --- a/tips/introduction.html +++ b/tips/introduction.html @@ -43,7 +43,7 @@
Skip to content

Tips

In this section we’ll share different tips that you can help you developing with the KDK.

Application development

Useful tips when developing.

Mobile configuration

Usefuld tips to configure the mobile applications.

- + \ No newline at end of file diff --git a/tips/mobile-configuration.html b/tips/mobile-configuration.html index 55048f594..9b810f278 100644 --- a/tips/mobile-configuration.html +++ b/tips/mobile-configuration.html @@ -56,7 +56,7 @@ openssl pkcs12 -export -out ios-dev.p12 -inkey ios-dev.key -in ios-dev.pem -passin pass:password -passout pass:password

If you'd like to view the content of a certificate:

openssl x509 -in ios-dev.cer -inform der -text
 // p12 file
 openssl pkcs12 -in ios-dev.p12 -nodes -passin pass:password | openssl x509 -noout -subject
- + \ No newline at end of file diff --git a/tools/browsers.html b/tools/browsers.html index f8d70a9ca..f6f027532 100644 --- a/tools/browsers.html +++ b/tools/browsers.html @@ -43,7 +43,7 @@
Skip to content
- + \ No newline at end of file diff --git a/tools/cli.html b/tools/cli.html index 770339b16..738184c38 100644 --- a/tools/cli.html +++ b/tools/cli.html @@ -97,7 +97,7 @@ $ travis login $ travis encrypt-file ssh.pem

Add the output to your build script:

bash
before_install:
   - openssl aes-256-cbc -K $encrypted_12c8071d2874_key -iv $encrypted_12c8071d2874_iv -in ssh.pem.enc -out ssh.pem -d
- + \ No newline at end of file diff --git a/tools/db.html b/tools/db.html index 7985acd6c..ce5e8bed0 100644 --- a/tools/db.html +++ b/tools/db.html @@ -43,7 +43,7 @@
Skip to content

Database tools

MongoDB

GUI

As it offers a similar user experience than Mongo Atlas we prefer to use Compass.

We previously also used Robo 3T.

Useful commands

Export a given collection from a given DB using a query in a JSON file: mongoexport -d krawler-test -c world_cities_csv -q "{ 'properties.country': 'France' }" --jsonArray --out file.json

Export a given collection from a given DB using a query in a CSV file: mongoexport -d krawler-test -c world_cities_csv -q "{ 'properties.country': 'France' }" --type csv --fields properties.country,properties.pop --out file.csv

- + \ No newline at end of file diff --git a/tools/documentation.html b/tools/documentation.html index 7449ec8c6..b16cf913d 100644 --- a/tools/documentation.html +++ b/tools/documentation.html @@ -224,7 +224,7 @@ keep-history: true on: branch: master

TIP

You must set the secure variable GITHUB_TOKEN in your Travis CI project settings

Working with diagrams

We use two distinct tools to work with diagrams:

To be able to include the diagrams within the documentation, we adopted the following methodology:

Draw.io

  1. make it with draw.io and store it in this folder
  2. export it as SVG/PNG in the root assets folder
  3. reference it in the documentation using a link like this ![My legend](https://raw.githubusercontent.com/kalisio/kdk/master/images/my-diagram.png)

mermaid

  1. install the mermaid CLI
  2. start from the hooks diagram template file
  3. output the SVG/PNG file in the root assets folder using mmdc -i ./my-hooks-diagram.mmd -t neutral -b transparent -o my-hooks-diagram.svg
  4. reference it in the documentation using a link like this ![My legend](https://raw.githubusercontent.com/kalisio/kdk/master/images/my-diagram.png)

The template looks like this: Hooks Diagram Template

- + \ No newline at end of file diff --git a/tools/infrastructure.html b/tools/infrastructure.html index b42984e96..baa6f2368 100644 --- a/tools/infrastructure.html +++ b/tools/infrastructure.html @@ -53,7 +53,7 @@ docker-compose down ... docker-compose up ...

Check why a swarm service did not start (empty logs, no replica):

bash
docker service ps --no-trunc {serviceName}

To access host in Docker Desktop Edition on Windows or Mac use the special DNS name host.docker.internal.

Traefik

Extract access logs for a given date time: cat access.log | grep "10/Mar/2020:02" > access-10-03-2020-03.log Check access logs for a given HTTP error code: cat access.log | grep "1.0\" 404" or cat access.log | grep "2.0\" 404" Gzip access logs: gzip -c access.log > access.log.gz

Scaleway

A step-by-step configuration of a new server with Docker and a single logical volume.

Networking

List all running ssh sessions: netstat -tnpa | grep 'ESTABLISHED.*sshd'

List all ssh session attempts: cat /var/log/auth.log

Development domains

Some development tasks like OAuth2 authentication have strict security concerns so that you cannot use localhost, non-standard ports or need to enforce HTTPS in all URLs. Here is how to setup a "fake" domain on your host.

Let's say we have our app running on localhost:8080 in HTTP or localhost:8083 in HTTPS. First, edit the hosts file (/etc/hosts under Linux or C:\Windows\System32\drivers\etc\hosts under Windows) and add this line to redirect the domain to local host:

127.0.0.1 test.airbusoidc.com

Then, since the hosts file does not allow to manage port redirections we need to do so using the operating system network tools.

Windows

To see what is currently running:

bash
netstat -a -n -p TCP | grep "LISTENING"

To add port redirection for HTTP:

bash
netsh interface portproxy add v4tov4 listenport=80 listenaddress=127.0.0.1 connectport=8080 connectaddress=127.0.0.1

To add port redirection for HTTPS:

bash
netsh interface portproxy add v4tov4 listenport=443 listenaddress=127.0.0.1 connectport=8083 connectaddress=127.0.0.1

To see running proxied port:

bash
netsh interface portproxy show v4tov4

To see remove proxied port:

bash
netsh interface portproxy delete v4tov4 listenport=80 listenaddress=127.0.0.1

Linux

First enable port redirection:

bash
echo "1" > /proc/sys/net/ipv4/ip_forward

Then add port redirect:

bash
iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8080`
 iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to 8080`

To remove simply replace in the previous command the -D switch instead of the -A switch.

- + \ No newline at end of file diff --git a/tools/introduction.html b/tools/introduction.html index 4ee2df85d..d254d9068 100644 --- a/tools/introduction.html +++ b/tools/introduction.html @@ -43,7 +43,7 @@
Skip to content

Tools

At Kalisio we are using a large number of different tools to support application development and data generation.

CLI

Useful command line tools.

Browsers

Useful browser-based tools.

Databases

Useful tools to manage databases.

Infrastructure

Useful infrastructure tips and tools.

Documentation

Useful tips for documenting the projets.

- + \ No newline at end of file