You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Go to file
Debora Crescenzo 09f639c935
MT#61724 Dependencies upgrade January
3 months ago
.yarn/releases MT#61534 Improve bundling 5 months ago
bin MT#61209 Upgrade to eslint 9.14.0 and add JS Policy's rules 5 months ago
debian Release new version 13.2.0.0+0~mr13.2.0.0 5 months ago
doc TT#96253 Upgrade to Quasar 1.14.1 5 years ago
env TT#142700 CSC: Create a PoC integration of the VoIP(NGCP) call using Javascript library JsSip in combination with Kamailio's WebSocket module 4 years ago
public MT#60860 Update new sipwise logo in CSC 8 months ago
src MT#59913 Add new Portuguese language to soundset 4 months ago
t MT#61209 Upgrade to eslint 9.14.0 and add JS Policy's rules 5 months ago
test MT#61209 Upgrade to eslint 9.14.0 and add JS Policy's rules 5 months ago
.babelrc TT#88909 Migrate Quasar to version 1.14.0 5 years ago
.editorconfig TT#111551 Convert Tabs to Spaces 4 years ago
.gitignore MT#57776 update dockerfile to make python csc tests work on debian 12 2 years ago
.gitreview TT#37304 CallForwarding: As a Customer, I want to enable/disable calls to my own number 7 years ago
.mailmap TT#91650 Add a .mailmap file to correct author information 5 years ago
.npmrc TT#127353 Maintenance - Upgrade vulnerable dependencies 4 years ago
.postcssrc.js TT#111551 Convert Tabs to Spaces 4 years ago
.stylintrc TT#23018 Setup: Create and prepare project skeleton for new CSC Web UI 8 years ago
.yarnrc MT#61534 Improve bundling 5 months ago
CONTRIBUTING.md TT#71950 Fix typos 5 years ago
README.md MT#61209 Upgrade to eslint 9.14.0 and add JS Policy's rules 5 months ago
TESTDATA.md TT#175000 Remove rtcengine support 2 years ago
babel.config.js TT#111551 Convert Tabs to Spaces 4 years ago
dev-config.sh TT#175000 Remove rtcengine support 2 years ago
dev.sh TT#23018 Setup: Create and prepare project skeleton for new CSC Web UI 8 years ago
eslint.config.mjs MT#61209 Upgrade to eslint 9.14.0 and add JS Policy's rules 5 months ago
jest.config.js MT#58893 Fix build failures for missing jest module 1 year ago
jsconfig.json TT#88909 Migrate Quasar to version 1.14.0 5 years ago
package.json MT#61724 Dependencies upgrade January 3 months ago
quasar.conf.dev.proxy.js MT#61209 Upgrade to eslint 9.14.0 and add JS Policy's rules 5 months ago
quasar.conf.js MT#61724 Dependencies upgrade January 3 months ago
quasar.extensions.json TT#88909 Migrate Quasar to version 1.14.0 5 years ago
quasar.testing.json TT#88909 Migrate Quasar to version 1.14.0 5 years ago
tox.ini TT#79804 allow longer lines for pep8 check 5 years ago
yarn.lock MT#61724 Dependencies upgrade January 3 months ago

README.md

Customer Self-Care Web UI

Development Quick Start for internal developers

Run development environment in Docker

This is the preferred way to work with. If you have any problems with Docker, you can fallback to the method described in the next chapter.

yarn run dev:docker dev-web-trunk.mgm.sipwise.com

Run development environment in your system of choice

yarn run config dev-web-trunk.mgm.sipwise.com
yarn run dev

Technology

Vue.js and Quasar

After a test phase with Sencha Ext JS we decided to use Vue.js in combination with the Quasar Framework.

Developers basics

We highly recommend the following courses to understand the principles and ultimately the code:

In addition, we also recommend the following Quasar Framework tutorials:

Project Guide

Translations

To keep translation files consistent and updated please run i18n:extract command before each commit to the GIT repo.

yarn run i18n:extract

That CLI command will collect all new translation keys from the JS source code, and will place those keys into all translation files in a proper format. Note that currently the command is set to use bash. If you prefer using sh change the package.json as below:

"i18n:extract": "sh ./bin/vue-i18n-extract/extract.sh",
"i18n:extract-report": "sh ./bin/vue-i18n-extract/extract.sh report"

Example of the JS code with translations:

const someOptions = {
    label: this.$t('Remove message'),
    message: this.$t('The {email} will be removed. Are you sure?', { email: this.email })
}

Important: We are trying to avoid usage of the dynamic keys (example below) because it's very difficult to detect and collect automatically.

Example (anti-pattern):

function getTranslatedMessage (weatherState) {
    return this.$t('Tooday is ' + weatherState)
}

Try to avoid such code and use text messages with substitution variables (like email in example above) or if there are only a couple similar messages, you can use a map object to convert some exact state to exact translation message. But if it's really impossible to do, and you have to use dynamic keys, you should place such keys to the English translation file manually and execute i18n:extract which will do all the rest.

For example, for the code above, you would need to place next lines into en.json:

{
    ...
    "Today is sunny": "",
    "Today is windy": "",
    "Today is cloudy": ""
}

Note: if you want to see information about missed or possible unused translation keys you could run i18n:extract-report command. It will just display detailed report without any modifications in the language files.

Keep in mind that some of "Unused translations" keys might be dynamic translation keys which cannot be detected in source code automatically and were added manually.

yarn run i18n:extract-report

Add a new page

In order to add a new page you need to go along the following steps:

  • Create a new page component using the following naming pattern

    src/pages/CscPageNewFeature.vue

  • Create a route and add it to the route file

    src/router/routes.js

{
    path: '/user/new-feature',
    component: CscPageNewFeature,
    meta: {
        title: i18n.t('New features'),
        subtitle: i18n.t('New features sub-title')
    }
}
  • Add new feature to the main menu

    src/components/CscMainMenuTop.vue

{
    to: '/user/new-feature',
    icon: 'fancy_icon',
    label: this.$t('New features'),
    sublabel: this.$t('New features sub-title'),
    visible: true
}

Dialogs

Example dialog

The basic dialog component is src/components/CscDialog.vue.

How to create a new custom dialog

Check the example implementation in src/components/CscDialogChangePassword.vue.

How to call custom dialogs from within a Vue.js Component method

To reduce the boilerplate code of dialog components, we call Dialogs via Quasar Dialog Plugin.

this.$q.dialog({
    component: CscDialogChangePassword,
    parent: this
}).onOk((password) => {
    this.changeWebPassword(password)
})

NGCP API

All API functions are located in src/api. The file src/api/common.js exports basic convenient functions to perform API requests.

Check API Documentation for further details.

Authentication

The standard authentication method to access the API from the browser is the JSON Web Token (JWT) which is specified in RFC7519

After the login request, the JWT is stored in the LocalStorage and is added automatically on each API request.

Fetch a list of items

const list = await getList({
    resource: 'subscribers'
})
list.items.forEach(subscriber => {
    console.log(subscriber.webusername)
})

Fetch a paginated list of items

const list = await getList({
    resource: 'subscribers',
    page: 1,
    rows: 25
})
console.log(list.lastPage)

Fetch a single item

const subscriber = await get({
    resource: 'subscribers',
    resourceId: 21
})
console.log(subscriber.webusername)

Create a new item

If you use post, you create the item and get back the sanitised data. The method postMinimal does exactly the same, except that the body is empty.

const subscriber = await post({
    resource: 'subscribers',
    body: {
        webusername: 'alice',
        ...
    }
})
console.log(subscriber.webusername)
await postMinimal({
    resource: 'subscribers',
    body: {
        webusername: 'alice',
        ...
    }
})

Update an existing item

This method helps to update an entire item at once.

const subscriber = await put({
    resource: 'subscribers',
    resourceId: 21,
    body: {
        webusername: 'bob',
        ...
    }
})
console.log(subscriber.webusername)
await putMinimal({
    resource: 'subscribers',
    resourceId: 21,
    body: {
        webusername: 'bob',
        ...
    }
})

Update a specific field on an existing item

This is the preferred method to update single fields on an item.

await patchReplace({
    resource: 'subscribers',
    resourceId: 21,
    fieldPath: 'webusername',
    value: 'carol'
})
const subscriber = await patchReplaceFull({
    resource: 'subscribers',
    resourceId: 21,
    fieldPath: 'webusername',
    value: 'dave'
})
console.log(subscriber.webusername)

### Troubleshooting

If you get a CORS error when trying to login, ssh in your machine and amend the flag `www_admin.http_csc.csc_dev` to yes.