From 515234187a18832f68e26030cf240a89944b9b55 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Sun, 10 Nov 2019 11:08:44 +0100 Subject: [PATCH] First working version --- e2e/helpers/extensions.js | 2 +- e2e/helpers/selectors.js | 22 +- .../02-client-module/01_create_client.spec.js | 8 +- e2e/paths/02-client-module/14_balance.spec.js | 8 +- e2e/paths/04-item-module/01_summary.spec.js | 18 +- .../08_create_and_clone.spec.js | 16 +- .../04-item-module/09_regularize.spec.js | 32 +- .../04-item-module/10_item_index.spec.js | 8 +- e2e/paths/04-item-module/11_item_log.spec.js | 4 +- .../01-sale/02_edit_sale.spec.js | 4 +- e2e/paths/05-ticket-module/09_weekly.spec.js | 12 +- e2e/paths/05-ticket-module/11_diary.spec.js | 8 +- .../05-ticket-module/12_descriptor.spec.js | 22 +- .../06-claim-module/06_descriptor.spec.js | 4 +- .../01_descriptor.spec.js | 16 +- front/core/components/autocomplete/index.js | 3 +- front/core/components/button-menu/index.js | 5 +- front/core/components/button/style.scss | 6 +- front/core/components/check/style.scss | 2 +- front/core/components/date-picker/index.js | 4 +- front/core/components/dialog/index.js | 12 +- front/core/components/dialog/index.spec.js | 19 +- front/core/components/dialog/style.scss | 2 +- front/core/components/drop-down/index.js | 17 +- front/core/components/field/index.html | 3 +- front/core/components/field/style.scss | 47 ++- front/core/components/icon-button/style.scss | 2 +- front/core/components/index.js | 1 + front/core/components/list/style.scss | 119 +++++-- front/core/components/popup/index.js | 23 +- front/core/components/radio/style.scss | 4 +- front/core/components/range/style.scss | 8 +- .../core/components/searchbar/searchbar.html | 16 +- front/core/components/searchbar/searchbar.js | 302 ++++++++++-------- front/core/components/searchbar/style.scss | 35 +- front/core/components/slot/index.js | 81 +++++ front/core/components/slot/portal.js | 28 ++ front/core/components/slot/style.scss | 3 + front/core/components/spinner/spinner.html | 1 + front/core/components/spinner/style.scss | 2 +- front/core/components/table/style.scss | 2 +- front/core/components/toggle/style.scss | 4 +- front/core/components/wday-picker/style.scss | 2 +- front/core/directives/id.js | 17 +- front/core/lib/component.js | 3 + front/core/lib/focus.js | 16 + front/core/lib/index.js | 3 +- front/core/module.js | 23 +- front/core/services/interceptor.js | 6 +- front/core/styles/global.scss | 4 + front/core/styles/variables.scss | 29 +- front/core/vendor.js | 2 + front/package-lock.json | 5 + front/package.json | 1 + front/salix/components/app/app.html | 29 +- front/salix/components/app/app.js | 25 +- front/salix/components/app/style.scss | 98 +----- front/salix/components/descriptor/style.scss | 2 +- front/salix/components/home/home.html | 2 +- front/salix/components/home/style.scss | 2 +- front/salix/components/index.js | 5 +- front/salix/components/layout/index.html | 69 ++++ front/salix/components/layout/index.js | 19 ++ .../salix/components/{app => layout}/logo.svg | 0 front/salix/components/layout/style.scss | 121 +++++++ .../salix/components/left-menu/left-menu.html | 31 +- front/salix/components/left-menu/left-menu.js | 44 +-- front/salix/components/left-menu/style.scss | 51 +-- front/salix/components/login/login.js | 2 + .../salix/components/main-menu/main-menu.html | 38 +-- front/salix/components/main-menu/main-menu.js | 7 +- front/salix/components/main-menu/style.scss | 51 ++- front/salix/components/module-card/index.js | 29 ++ front/salix/components/module-card/style.scss | 5 + front/salix/components/module-main/index.html | 4 + front/salix/components/module-main/index.js | 15 + front/salix/components/module-main/style.scss | 5 + front/salix/components/side-menu/side-menu.js | 38 ++- front/salix/components/side-menu/style.scss | 8 +- front/salix/components/summary/style.scss | 1 + front/salix/components/topbar/style.scss | 9 +- front/salix/components/topbar/topbar.js | 6 - .../salix/components/user-popover/style.scss | 2 +- front/salix/module.js | 7 +- front/salix/routes.js | 63 ++-- front/salix/styles/misc.scss | 15 +- modules/agency/front/basic-data/index.html | 11 +- modules/agency/front/card/index.html | 8 +- modules/agency/front/card/index.js | 29 +- modules/agency/front/card/index.spec.js | 33 +- modules/agency/front/create/index.html | 155 ++++----- modules/agency/front/delivery-days/index.html | 9 +- modules/agency/front/events/index.html | 109 +++---- modules/agency/front/index/index.html | 105 +++--- modules/agency/front/location/index.html | 39 +-- modules/agency/front/location/index.js | 9 +- modules/agency/front/location/style.scss | 6 +- modules/agency/front/main/index.html | 25 +- modules/agency/front/main/index.js | 7 +- modules/agency/front/main/style.scss | 18 -- modules/agency/front/routes.json | 18 +- modules/agency/front/search-panel/index.html | 4 +- modules/claim/front/basic-data/index.html | 2 +- modules/claim/front/card/index.html | 12 +- modules/claim/front/card/index.js | 43 +-- modules/claim/front/card/index.spec.js | 26 +- modules/claim/front/development/index.html | 2 +- modules/claim/front/index.js | 1 + modules/claim/front/index/index.html | 113 +++---- modules/claim/front/main/index.html | 11 + modules/claim/front/main/index.js | 9 + modules/claim/front/routes.json | 21 +- .../client/front/address/create/index.html | 2 +- modules/client/front/address/edit/index.html | 2 +- modules/client/front/billing-data/index.html | 2 +- modules/client/front/card/index.html | 12 +- modules/client/front/card/index.js | 24 +- modules/client/front/card/index.spec.js | 24 +- modules/client/front/contact/index.html | 2 +- modules/client/front/create/index.html | 295 ++++++++--------- .../front/credit-insurance/create/index.html | 2 +- .../insurance/create/index.html | 2 +- modules/client/front/credit/create/index.html | 2 +- modules/client/front/dms/create/index.html | 4 +- modules/client/front/dms/edit/index.html | 2 +- modules/client/front/fiscal-data/index.html | 2 +- modules/client/front/greuge/create/index.html | 2 +- modules/client/front/index.js | 1 + modules/client/front/index/index.html | 105 +++--- modules/client/front/index/index.js | 13 +- modules/client/front/main/index.html | 11 + modules/client/front/main/index.js | 9 + modules/client/front/note/create/index.html | 2 +- .../client/front/recovery/create/index.html | 2 +- modules/client/front/routes.json | 57 ++-- modules/client/front/sample/create/index.html | 2 +- modules/client/front/web-access/index.html | 2 +- modules/invoiceOut/front/card/index.html | 12 +- modules/invoiceOut/front/card/index.js | 27 +- modules/invoiceOut/front/index.js | 1 + modules/invoiceOut/front/index/index.html | 123 ++++--- modules/invoiceOut/front/main/index.html | 11 + modules/invoiceOut/front/main/index.js | 9 + modules/invoiceOut/front/routes.json | 7 +- modules/item/front/barcode/index.html | 2 +- modules/item/front/basic-data/index.html | 2 +- modules/item/front/botanical/index.html | 2 +- modules/item/front/card/index.html | 12 +- modules/item/front/card/index.js | 24 +- modules/item/front/card/index.spec.js | 29 +- modules/item/front/create/index.html | 114 ++++--- modules/item/front/diary/index.html | 2 +- modules/item/front/index.js | 1 + modules/item/front/index/index.html | 226 ++++++------- modules/item/front/index/index.js | 16 - modules/item/front/main/index.html | 12 + modules/item/front/main/index.js | 9 + modules/item/front/niche/index.html | 2 +- modules/item/front/request/index.html | 212 ++++++------ modules/item/front/routes.json | 30 +- modules/item/front/tags/index.html | 2 +- modules/item/front/tax/index.html | 2 +- modules/order/front/basic-data/index.html | 2 +- modules/order/front/card/index.html | 12 +- modules/order/front/card/index.js | 72 ++--- modules/order/front/card/index.spec.js | 60 +--- modules/order/front/catalog/index.html | 3 +- modules/order/front/create/index.html | 18 +- modules/order/front/descriptor/index.js | 1 + modules/order/front/index.js | 1 + modules/order/front/index/index.html | 131 ++++---- modules/order/front/main/index.html | 11 + modules/order/front/main/index.js | 9 + modules/order/front/routes.json | 19 +- modules/route/front/basic-data/index.html | 2 +- modules/route/front/card/index.html | 12 +- modules/route/front/card/index.js | 35 +- modules/route/front/create/index.html | 104 +++--- modules/route/front/descriptor/index.js | 4 +- modules/route/front/index.js | 1 + modules/route/front/index/index.html | 104 +++--- modules/route/front/index/index.js | 30 +- modules/route/front/index/style.scss | 5 - modules/route/front/main/index.html | 12 + modules/route/front/main/index.js | 26 ++ modules/route/front/routes.json | 16 +- modules/ticket/front/basic-data/index.html | 24 +- modules/ticket/front/card/index.html | 12 +- modules/ticket/front/card/index.js | 57 ++-- modules/ticket/front/card/index.spec.js | 37 +-- modules/ticket/front/create/index.html | 18 +- modules/ticket/front/dms/create/index.html | 4 +- modules/ticket/front/dms/edit/index.html | 4 +- modules/ticket/front/index.js | 1 + modules/ticket/front/index/index.html | 274 ++++++++-------- modules/ticket/front/index/index.js | 15 +- modules/ticket/front/main/index.html | 11 + modules/ticket/front/main/index.js | 9 + modules/ticket/front/note/index.html | 2 +- .../ticket/front/request/create/index.html | 2 +- modules/ticket/front/routes.json | 42 +-- modules/ticket/front/sale/index.html | 4 +- modules/ticket/front/tracking/edit/index.html | 2 +- modules/ticket/front/weekly/create/index.html | 126 ++++---- modules/ticket/front/weekly/index/index.html | 146 +++++---- modules/travel/front/basic-data/index.html | 2 +- modules/travel/front/card/index.html | 12 +- modules/travel/front/card/index.js | 31 +- modules/travel/front/descriptor/index.js | 2 +- modules/travel/front/index.js | 1 + modules/travel/front/index/index.html | 103 +++--- modules/travel/front/main/index.html | 11 + modules/travel/front/main/index.js | 9 + modules/travel/front/routes.json | 15 +- modules/worker/front/account/index.html | 2 +- modules/worker/front/basic-data/index.html | 2 +- modules/worker/front/calendar/index.html | 26 +- modules/worker/front/card/index.html | 12 +- modules/worker/front/card/index.js | 25 +- modules/worker/front/department/index.html | 37 +-- modules/worker/front/index.js | 1 + modules/worker/front/index/index.html | 96 +++--- modules/worker/front/index/index.js | 6 +- modules/worker/front/main/index.html | 11 + modules/worker/front/main/index.js | 9 + modules/worker/front/pbx/index.html | 2 +- modules/worker/front/phones/index.html | 2 +- modules/worker/front/routes.json | 40 +-- modules/worker/front/time-control/index.html | 120 ++++--- 229 files changed, 3278 insertions(+), 2925 deletions(-) create mode 100644 front/core/components/slot/index.js create mode 100644 front/core/components/slot/portal.js create mode 100644 front/core/components/slot/style.scss create mode 100644 front/core/lib/focus.js create mode 100644 front/salix/components/layout/index.html create mode 100644 front/salix/components/layout/index.js rename front/salix/components/{app => layout}/logo.svg (100%) create mode 100644 front/salix/components/layout/style.scss create mode 100644 front/salix/components/module-card/index.js create mode 100644 front/salix/components/module-card/style.scss create mode 100644 front/salix/components/module-main/index.html create mode 100644 front/salix/components/module-main/index.js create mode 100644 front/salix/components/module-main/style.scss delete mode 100644 modules/agency/front/main/style.scss create mode 100644 modules/claim/front/main/index.html create mode 100644 modules/claim/front/main/index.js create mode 100644 modules/client/front/main/index.html create mode 100644 modules/client/front/main/index.js create mode 100644 modules/invoiceOut/front/main/index.html create mode 100644 modules/invoiceOut/front/main/index.js create mode 100644 modules/item/front/main/index.html create mode 100644 modules/item/front/main/index.js create mode 100644 modules/order/front/main/index.html create mode 100644 modules/order/front/main/index.js delete mode 100644 modules/route/front/index/style.scss create mode 100644 modules/route/front/main/index.html create mode 100644 modules/route/front/main/index.js create mode 100644 modules/ticket/front/main/index.html create mode 100644 modules/ticket/front/main/index.js create mode 100644 modules/travel/front/main/index.html create mode 100644 modules/travel/front/main/index.js create mode 100644 modules/worker/front/main/index.html create mode 100644 modules/worker/front/main/index.js diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 46c43a254..e46ad79ba 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -346,7 +346,7 @@ let actions = { .write('vn-searchbar input', searchValue) .click('vn-searchbar vn-icon[icon="search"]') .wait(100) - .waitForNumberOfElements('.searchResult', 1) + .waitForNumberOfElements('.search-result', 1) .evaluate(() => { return document.querySelector('ui-view vn-card vn-table') != null; }) diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index dc6083b39..52e6e256b 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -23,7 +23,7 @@ export default { clientsIndex: { searchClientInput: `vn-textfield input`, searchButton: 'vn-searchbar vn-icon[icon="search"]', - searchResult: 'vn-client-index .vn-list-item', + search-result: 'vn-client-index .vn-item', createClientButton: `vn-float-button`, othersButton: 'vn-left-menu li[name="Others"] > a' }, @@ -182,9 +182,9 @@ export default { itemsIndex: { searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]', createItemButton: `vn-float-button`, - searchResult: 'vn-item-index a.vn-tr', - searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]', - searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', + search-result: 'vn-item-index a.vn-tr', + search-resultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]', + search-resultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', searchItemInput: 'vn-searchbar vn-textfield input', searchButton: 'vn-searchbar vn-icon[icon="search"]', @@ -326,9 +326,9 @@ export default { openAdvancedSearchButton: 'vn-ticket-index vn-searchbar .append vn-icon[icon="arrow_drop_down"]', advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[ng-model="filter.refFk"] input', newTicketButton: 'vn-ticket-index > a', - searchResult: 'vn-ticket-index vn-card > vn-table > div > vn-tbody > a.vn-tr', + search-result: 'vn-ticket-index vn-card > vn-table > div > vn-tbody > a.vn-tr', searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr', - searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)', + search-resultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)', searchTicketInput: `vn-ticket-index vn-textfield input`, searchWeeklyTicketInput: `vn-ticket-weekly-index vn-textfield input`, searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon=clear]', @@ -517,7 +517,7 @@ export default { }, claimsIndex: { searchClaimInput: `vn-claim-index vn-textfield input`, - searchResult: 'vn-claim-index vn-card > vn-table > div > vn-tbody > a', + search-result: 'vn-claim-index vn-card > vn-table > div > vn-tbody > a', searchButton: 'vn-claim-index vn-searchbar vn-icon[icon="search"]' }, claimDescriptor: { @@ -580,9 +580,9 @@ export default { isPaidWithManaCheckbox: 'vn-check[ng-model="$ctrl.claim.isChargedToMana"]' }, ordersIndex: { - searchResult: 'vn-order-index vn-card > vn-table > div > vn-tbody > a.vn-tr', - searchResultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)', - searchResultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)', + search-result: 'vn-order-index vn-card > vn-table > div > vn-tbody > a.vn-tr', + search-resultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)', + search-resultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)', searchOrderInput: `vn-order-index vn-textfield input`, searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]', createOrderButton: `vn-float-button`, @@ -722,7 +722,7 @@ export default { invoiceOutIndex: { searchInvoiceOutInput: `vn-invoice-out-index vn-textfield input`, searchButton: 'vn-invoice-out-index vn-searchbar vn-icon[icon="search"]', - searchResult: 'vn-invoice-out-index vn-card > vn-table > div > vn-tbody > a.vn-tr', + search-result: 'vn-invoice-out-index vn-card > vn-table > div > vn-tbody > a.vn-tr', }, invoiceOutDescriptor: { moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[icon=more_vert]', diff --git a/e2e/paths/02-client-module/01_create_client.spec.js b/e2e/paths/02-client-module/01_create_client.spec.js index f2fe30464..abac46535 100644 --- a/e2e/paths/02-client-module/01_create_client.spec.js +++ b/e2e/paths/02-client-module/01_create_client.spec.js @@ -13,8 +13,8 @@ describe('Client create path', () => { const result = await nightmare .write(selectors.clientsIndex.searchClientInput, 'Carol Danvers') .waitToClick(selectors.clientsIndex.searchButton) - .waitForNumberOfElements(selectors.clientsIndex.searchResult, 0) - .countElement(selectors.clientsIndex.searchResult); + .waitForNumberOfElements(selectors.clientsIndex.search-result, 0) + .countElement(selectors.clientsIndex.search-result); expect(result).toEqual(0); }); @@ -117,8 +117,8 @@ describe('Client create path', () => { const result = await nightmare .write(selectors.clientsIndex.searchClientInput, 'Carol Danvers') .waitToClick(selectors.clientsIndex.searchButton) - .waitForNumberOfElements(selectors.clientsIndex.searchResult, 1) - .countElement(selectors.clientsIndex.searchResult); + .waitForNumberOfElements(selectors.clientsIndex.search-result, 1) + .countElement(selectors.clientsIndex.search-result); expect(result).toEqual(1); }); diff --git a/e2e/paths/02-client-module/14_balance.spec.js b/e2e/paths/02-client-module/14_balance.spec.js index b661d998b..e056b5eea 100644 --- a/e2e/paths/02-client-module/14_balance.spec.js +++ b/e2e/paths/02-client-module/14_balance.spec.js @@ -135,16 +135,16 @@ describe('Client balance path', () => { let resultCount = await nightmare .write(selectors.clientsIndex.searchClientInput, 'Petter Parker') .waitToClick(selectors.clientsIndex.searchButton) - .waitForNumberOfElements(selectors.clientsIndex.searchResult, 1) - .countElement(selectors.clientsIndex.searchResult); + .waitForNumberOfElements(selectors.clientsIndex.search-result, 1) + .countElement(selectors.clientsIndex.search-result); expect(resultCount).toEqual(1); }); it(`should click on the search result to access to the client's balance`, async() => { let url = await nightmare - .waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker') - .waitToClick(selectors.clientsIndex.searchResult) + .waitForTextInElement(selectors.clientsIndex.search-result, 'Petter Parker') + .waitToClick(selectors.clientsIndex.search-result) .waitToClick(selectors.clientBalance.balanceButton) .waitForURL('/balance') .parsedUrl(); diff --git a/e2e/paths/04-item-module/01_summary.spec.js b/e2e/paths/04-item-module/01_summary.spec.js index bd06ebef4..41737a7e6 100644 --- a/e2e/paths/04-item-module/01_summary.spec.js +++ b/e2e/paths/04-item-module/01_summary.spec.js @@ -14,16 +14,16 @@ describe('Item summary path', () => { .clearInput(selectors.itemsIndex.searchItemInput) .write(selectors.itemsIndex.searchItemInput, 'Ranged weapon longbow 2m') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 1) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 1) + .countElement(selectors.itemsIndex.search-result); expect(result).toEqual(1); }); it(`should click on the search result summary button to open the item summary popup`, async() => { const isVisible = await nightmare - .waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon longbow 2m') - .waitToClick(selectors.itemsIndex.searchResultPreviewButton) + .waitForTextInElement(selectors.itemsIndex.search-result, 'Ranged weapon longbow 2m') + .waitToClick(selectors.itemsIndex.search-resultPreviewButton) .isVisible(selectors.itemSummary.basicData); expect(isVisible).toBeTruthy(); @@ -84,16 +84,16 @@ describe('Item summary path', () => { .waitToClick(selectors.itemsIndex.searchButton) .write(selectors.itemsIndex.searchItemInput, 'Melee weapon combat fist 15cm') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 1) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 1) + .countElement(selectors.itemsIndex.search-result); expect(result).toEqual(1); }); it(`should now click on the search result summary button to open the item summary popup`, async() => { const isVisible = await nightmare - .waitForTextInElement(selectors.itemsIndex.searchResult, 'Melee weapon combat fist 15cm') - .waitToClick(selectors.itemsIndex.searchResultPreviewButton) + .waitForTextInElement(selectors.itemsIndex.search-result, 'Melee weapon combat fist 15cm') + .waitToClick(selectors.itemsIndex.search-resultPreviewButton) .isVisible(selectors.itemSummary.basicData); @@ -151,7 +151,7 @@ describe('Item summary path', () => { it(`should navigate to the one of the items detailed section`, async() => { const url = await nightmare - .waitToClick(selectors.itemsIndex.searchResult) + .waitToClick(selectors.itemsIndex.search-result) .waitForURL('summary') .parsedUrl(); diff --git a/e2e/paths/04-item-module/08_create_and_clone.spec.js b/e2e/paths/04-item-module/08_create_and_clone.spec.js index 8f4952fb1..0fe8596c3 100644 --- a/e2e/paths/04-item-module/08_create_and_clone.spec.js +++ b/e2e/paths/04-item-module/08_create_and_clone.spec.js @@ -14,8 +14,8 @@ describe('Item Create/Clone path', () => { .clearInput(selectors.itemsIndex.searchItemInput) .write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 0) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 0) + .countElement(selectors.itemsIndex.search-result); expect(result).toEqual(0); }); @@ -99,16 +99,16 @@ describe('Item Create/Clone path', () => { .clearInput(selectors.itemsIndex.searchItemInput) .write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 1) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 1) + .countElement(selectors.itemsIndex.search-result); expect(result).toEqual(1); }); it(`should clone the Infinity Gauntlet`, async() => { const url = await nightmare - .waitForTextInElement(selectors.itemsIndex.searchResult, 'Infinity Gauntlet') - .waitToClick(selectors.itemsIndex.searchResultCloneButton) + .waitForTextInElement(selectors.itemsIndex.search-result, 'Infinity Gauntlet') + .waitToClick(selectors.itemsIndex.search-resultCloneButton) .waitToClick(selectors.itemsIndex.acceptClonationAlertButton) .waitForURL('tags') .parsedUrl(); @@ -122,8 +122,8 @@ describe('Item Create/Clone path', () => { .clearInput(selectors.itemsIndex.searchItemInput) .write(selectors.itemsIndex.searchItemInput, 'Infinity Gauntlet') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 2) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 2) + .countElement(selectors.itemsIndex.search-result); expect(result).toEqual(2); }); diff --git a/e2e/paths/04-item-module/09_regularize.spec.js b/e2e/paths/04-item-module/09_regularize.spec.js index 242414372..82da8b01a 100644 --- a/e2e/paths/04-item-module/09_regularize.spec.js +++ b/e2e/paths/04-item-module/09_regularize.spec.js @@ -32,16 +32,16 @@ describe('Item regularize path', () => { .clearInput(selectors.itemsIndex.searchItemInput) .write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 1) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 1) + .countElement(selectors.itemsIndex.search-result); expect(resultCount).toEqual(1); }); it(`should click on the search result to access to the item tax`, async() => { const url = await nightmare - .waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon pistol 9mm') - .waitToClick(selectors.itemsIndex.searchResult) + .waitForTextInElement(selectors.itemsIndex.search-result, 'Ranged weapon pistol 9mm') + .waitToClick(selectors.itemsIndex.search-result) .waitForURL('/summary') .parsedUrl(); @@ -91,16 +91,16 @@ describe('Item regularize path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 'missing') .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should click on the search result to access to the ticket summary`, async() => { const url = await nightmare - .waitForTextInElement(selectors.ticketsIndex.searchResult, 'Missing') - .waitToClick(selectors.ticketsIndex.searchResult) + .waitForTextInElement(selectors.ticketsIndex.search-result, 'Missing') + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); @@ -138,16 +138,16 @@ describe('Item regularize path', () => { .clearInput(selectors.itemsIndex.searchItemInput) .write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 1) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 1) + .countElement(selectors.itemsIndex.search-result); expect(resultCount).toEqual(1); }); it(`should click on the search result to access to the item tax`, async() => { const url = await nightmare - .waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon pistol 9mm') - .waitToClick(selectors.itemsIndex.searchResult) + .waitForTextInElement(selectors.itemsIndex.search-result, 'Ranged weapon pistol 9mm') + .waitToClick(selectors.itemsIndex.search-result) .waitForURL('/summary') .parsedUrl(); @@ -181,16 +181,16 @@ describe('Item regularize path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 25) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should now click on the search result to access to the ticket summary`, async() => { const url = await nightmare - .waitForTextInElement(selectors.ticketsIndex.searchResult, '25') - .waitToClick(selectors.ticketsIndex.searchResult) + .waitForTextInElement(selectors.ticketsIndex.search-result, '25') + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); diff --git a/e2e/paths/04-item-module/10_item_index.spec.js b/e2e/paths/04-item-module/10_item_index.spec.js index b83b37c59..13604063b 100644 --- a/e2e/paths/04-item-module/10_item_index.spec.js +++ b/e2e/paths/04-item-module/10_item_index.spec.js @@ -38,10 +38,10 @@ describe('Item index path', () => { it('should navigate forth and back to see the images column is still visible', async() => { const imageVisible = await nightmare - .waitToClick(selectors.itemsIndex.searchResult) + .waitToClick(selectors.itemsIndex.search-result) .waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton) .waitToClick(selectors.itemsIndex.searchIcon) - .wait(selectors.itemsIndex.searchResult) + .wait(selectors.itemsIndex.search-result) .isVisible(selectors.itemsIndex.firstItemImage); expect(imageVisible).toBeTruthy(); @@ -75,10 +75,10 @@ describe('Item index path', () => { it('should now navigate forth and back to see the ids column is now visible', async() => { const idVisible = await nightmare - .waitToClick(selectors.itemsIndex.searchResult) + .waitToClick(selectors.itemsIndex.search-result) .waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton) .waitToClick(selectors.itemsIndex.searchIcon) - .wait(selectors.itemsIndex.searchResult) + .wait(selectors.itemsIndex.search-result) .isVisible(selectors.itemsIndex.firstItemId); expect(idVisible).toBeTruthy(); diff --git a/e2e/paths/04-item-module/11_item_log.spec.js b/e2e/paths/04-item-module/11_item_log.spec.js index cf3beb528..d1cdfedea 100644 --- a/e2e/paths/04-item-module/11_item_log.spec.js +++ b/e2e/paths/04-item-module/11_item_log.spec.js @@ -12,8 +12,8 @@ describe('Item log path', () => { const result = await nightmare .write(selectors.itemsIndex.searchItemInput, 'Knowledge artifact') .waitToClick(selectors.itemsIndex.searchButton) - .waitForNumberOfElements(selectors.itemsIndex.searchResult, 0) - .countElement(selectors.itemsIndex.searchResult); + .waitForNumberOfElements(selectors.itemsIndex.search-result, 0) + .countElement(selectors.itemsIndex.search-result); expect(result).toEqual(0); }); diff --git a/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js index 5a6d6cd62..c1b9996c6 100644 --- a/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket-module/01-sale/02_edit_sale.spec.js @@ -213,8 +213,8 @@ xdescribe('Ticket Edit sale path', () => { const result = await nightmare .write(selectors.claimsIndex.searchClaimInput, 4) .waitToClick(selectors.claimsIndex.searchButton) - .waitForNumberOfElements(selectors.claimsIndex.searchResult, 1) - .countElement(selectors.claimsIndex.searchResult); + .waitForNumberOfElements(selectors.claimsIndex.search-result, 1) + .countElement(selectors.claimsIndex.search-result); expect(result).toEqual(1); }); diff --git a/e2e/paths/05-ticket-module/09_weekly.spec.js b/e2e/paths/05-ticket-module/09_weekly.spec.js index a7a301d79..f9f6a6380 100644 --- a/e2e/paths/05-ticket-module/09_weekly.spec.js +++ b/e2e/paths/05-ticket-module/09_weekly.spec.js @@ -34,15 +34,15 @@ describe('Ticket descriptor path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 11) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should click on the search result to access to the ticket`, async() => { const url = await nightmare - .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); @@ -94,15 +94,15 @@ describe('Ticket descriptor path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 11) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should click on the search result to access to the ticket`, async() => { const url = await nightmare - .waitToClick(selectors.ticketsIndex.searchResult) + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); diff --git a/e2e/paths/05-ticket-module/11_diary.spec.js b/e2e/paths/05-ticket-module/11_diary.spec.js index aeec780e7..bd086c527 100644 --- a/e2e/paths/05-ticket-module/11_diary.spec.js +++ b/e2e/paths/05-ticket-module/11_diary.spec.js @@ -14,16 +14,16 @@ describe('Ticket diary path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 1) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should click on the search result to access to the ticket summary`, async() => { const url = await nightmare - .waitForTextInElement(selectors.ticketsIndex.searchResult, 'Bat cave') - .waitToClick(selectors.ticketsIndex.searchResult) + .waitForTextInElement(selectors.ticketsIndex.search-result, 'Bat cave') + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); diff --git a/e2e/paths/05-ticket-module/12_descriptor.spec.js b/e2e/paths/05-ticket-module/12_descriptor.spec.js index b9c6c7c87..4f405dd37 100644 --- a/e2e/paths/05-ticket-module/12_descriptor.spec.js +++ b/e2e/paths/05-ticket-module/12_descriptor.spec.js @@ -14,16 +14,16 @@ describe('Ticket descriptor path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 18) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should click on the search result to access to the ticket summary`, async() => { const url = await nightmare - .waitForTextInElement(selectors.ticketsIndex.searchResult, 'Cerebro') - .waitToClick(selectors.ticketsIndex.searchResult) + .waitForTextInElement(selectors.ticketsIndex.search-result, 'Cerebro') + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); @@ -69,9 +69,9 @@ describe('Ticket descriptor path', () => { const result = await nightmare .write(selectors.ticketsIndex.searchTicketInput, 18) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .wait(selectors.ticketsIndex.searchResultDate) - .waitToGetProperty(selectors.ticketsIndex.searchResultDate, 'innerText'); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .wait(selectors.ticketsIndex.search-resultDate) + .waitToGetProperty(selectors.ticketsIndex.search-resultDate, 'innerText'); expect(result).toContain(2000); }); @@ -83,16 +83,16 @@ describe('Ticket descriptor path', () => { .clearInput(selectors.ticketsIndex.searchTicketInput) .write(selectors.ticketsIndex.searchTicketInput, 16) .waitToClick(selectors.ticketsIndex.searchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); it(`should now click on the search result to access to the ticket summary`, async() => { const url = await nightmare - .waitForTextInElement(selectors.ticketsIndex.searchResult, 'Many Places') - .waitToClick(selectors.ticketsIndex.searchResult) + .waitForTextInElement(selectors.ticketsIndex.search-result, 'Many Places') + .waitToClick(selectors.ticketsIndex.search-result) .waitForURL('/summary') .parsedUrl(); diff --git a/e2e/paths/06-claim-module/06_descriptor.spec.js b/e2e/paths/06-claim-module/06_descriptor.spec.js index 67faaa224..75db0888c 100644 --- a/e2e/paths/06-claim-module/06_descriptor.spec.js +++ b/e2e/paths/06-claim-module/06_descriptor.spec.js @@ -63,8 +63,8 @@ describe('claim Descriptor path', () => { const result = await nightmare .write(selectors.claimsIndex.searchClaimInput, claimId) .waitToClick(selectors.claimsIndex.searchButton) - .waitForNumberOfElements(selectors.claimsIndex.searchResult, 0) - .countElement(selectors.claimsIndex.searchResult); + .waitForNumberOfElements(selectors.claimsIndex.search-result, 0) + .countElement(selectors.claimsIndex.search-result); expect(result).toEqual(0); }); diff --git a/e2e/paths/09-invoice-out-module/01_descriptor.spec.js b/e2e/paths/09-invoice-out-module/01_descriptor.spec.js index f170b87b0..34365b7ec 100644 --- a/e2e/paths/09-invoice-out-module/01_descriptor.spec.js +++ b/e2e/paths/09-invoice-out-module/01_descriptor.spec.js @@ -15,8 +15,8 @@ describe('InvoiceOut descriptor path', () => { .waitToClick(selectors.ticketsIndex.openAdvancedSearchButton) .write(selectors.ticketsIndex.advancedSearchInvoiceOut, 'T2222222') .waitToClick(selectors.ticketsIndex.advancedSearchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 1) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(1); }); @@ -36,8 +36,8 @@ describe('InvoiceOut descriptor path', () => { const result = await nightmare .write(selectors.invoiceOutIndex.searchInvoiceOutInput, 'T2222222') .waitToClick(selectors.invoiceOutIndex.searchButton) - .waitForNumberOfElements(selectors.invoiceOutIndex.searchResult, 1) - .countElement(selectors.invoiceOutIndex.searchResult); + .waitForNumberOfElements(selectors.invoiceOutIndex.search-result, 1) + .countElement(selectors.invoiceOutIndex.search-result); expect(result).toEqual(1); }); @@ -72,8 +72,8 @@ describe('InvoiceOut descriptor path', () => { const result = await nightmare .write(selectors.invoiceOutIndex.searchInvoiceOutInput, 'T2222222') .waitToClick(selectors.invoiceOutIndex.searchButton) - .waitForNumberOfElements(selectors.invoiceOutIndex.searchResult, 0) - .countElement(selectors.invoiceOutIndex.searchResult); + .waitForNumberOfElements(selectors.invoiceOutIndex.search-result, 0) + .countElement(selectors.invoiceOutIndex.search-result); expect(result).toEqual(0); }); @@ -94,8 +94,8 @@ describe('InvoiceOut descriptor path', () => { .waitToClick(selectors.ticketsIndex.openAdvancedSearchButton) .write(selectors.ticketsIndex.advancedSearchInvoiceOut, 'T2222222') .waitToClick(selectors.ticketsIndex.advancedSearchButton) - .waitForNumberOfElements(selectors.ticketsIndex.searchResult, 0) - .countElement(selectors.ticketsIndex.searchResult); + .waitForNumberOfElements(selectors.ticketsIndex.search-result, 0) + .countElement(selectors.ticketsIndex.search-result); expect(result).toEqual(0); }); diff --git a/front/core/components/autocomplete/index.js b/front/core/components/autocomplete/index.js index 9808fd667..0916b3691 100755 --- a/front/core/components/autocomplete/index.js +++ b/front/core/components/autocomplete/index.js @@ -208,11 +208,9 @@ export default class Autocomplete extends Field { onContainerKeyDown(event) { if (event.defaultPrevented) return; - switch (event.key) { case 'ArrowUp': case 'ArrowDown': - case 'Enter': this.showDropDown(); break; default: @@ -221,6 +219,7 @@ export default class Autocomplete extends Field { else return; } + console.log(event.key); } onContainerClick(event) { diff --git a/front/core/components/button-menu/index.js b/front/core/components/button-menu/index.js index 946e1fd7f..c19962b08 100644 --- a/front/core/components/button-menu/index.js +++ b/front/core/components/button-menu/index.js @@ -7,7 +7,7 @@ export default class ButtonMenu extends Button { constructor($element, $scope, $transclude) { super($element, $scope); this.$transclude = $transclude; - $element.on('click', e => this.onClick(e)); + $element.on('click', e => this.onButtonClick(e)); } get model() { @@ -41,8 +41,7 @@ export default class ButtonMenu extends Button { Object.assign(this.$.dropDown, props); } - onClick(event) { - if (this.disabled) return; + onButtonClick(event) { if (event.defaultPrevented) return; this.emit('open'); this.showDropDown(); diff --git a/front/core/components/button/style.scss b/front/core/components/button/style.scss index 74dcbcf9b..032c88cbb 100644 --- a/front/core/components/button/style.scss +++ b/front/core/components/button/style.scss @@ -39,19 +39,19 @@ } &.colored { color: white; - background-color: $color-main; + background-color: $color-button; box-shadow: 0 .15em .15em 0 rgba(0, 0, 0, .3); transition: background 200ms ease-in-out; &:not(.disabled) { &:hover, &:focus { - background-color: lighten($color-main, 10%); + background-color: lighten($color-button, 10%); } } } &.flat { - color: $color-main; + color: $color-button; background-color: transparent; box-shadow: none; transition: background 200ms ease-in-out; diff --git a/front/core/components/check/style.scss b/front/core/components/check/style.scss index 31715a2cd..b84b61ce5 100644 --- a/front/core/components/check/style.scss +++ b/front/core/components/check/style.scss @@ -19,7 +19,7 @@ } &.checked > .btn { border-color: transparent; - background-color: $color-main; + background-color: $color-button; & > .mark { top: 0; diff --git a/front/core/components/date-picker/index.js b/front/core/components/date-picker/index.js index 17ce19406..f88e26c9c 100644 --- a/front/core/components/date-picker/index.js +++ b/front/core/components/date-picker/index.js @@ -14,7 +14,9 @@ class DatePicker extends Field { let value = this.input.value; if (value) { - date = new Date(value); + let ymd = value.split('-') + .map(e => parseInt(e)); + date = new Date(...ymd); if (this.field) { let orgDate = this.field instanceof Date diff --git a/front/core/components/dialog/index.js b/front/core/components/dialog/index.js index 0891542a2..7a7cb5f9f 100644 --- a/front/core/components/dialog/index.js +++ b/front/core/components/dialog/index.js @@ -29,6 +29,10 @@ export default class Dialog extends Popup { * @return {Promise} A promise that will be resolved with response when dialog is closed */ show(data, responseHandler) { + if (this.shown) + return this.$q.reject(new Error('Dialog already shown')); + super.show(); + if (typeof data == 'function') { responseHandler = data; data = null; @@ -36,27 +40,27 @@ export default class Dialog extends Popup { this.data = data; this.showHandler = responseHandler; - super.show(); return this.$q(resolve => { this.resolve = resolve; }); } /** - * Hides the dialog. + * Hides the dialog resolving the promise returned by show(). * * @param {String} response The response */ hide(response) { if (!this.shown) return; - this.showHandler = null; super.hide(); + + this.showHandler = null; if (this.resolve) this.resolve(response); } /** - * Calls the response handler. + * Calls the response handlers. * * @param {String} response The response code * @return {Boolean} The response handler return diff --git a/front/core/components/dialog/index.spec.js b/front/core/components/dialog/index.spec.js index a898261fb..8c41bc060 100644 --- a/front/core/components/dialog/index.spec.js +++ b/front/core/components/dialog/index.spec.js @@ -28,14 +28,6 @@ describe('Component vnDialog', () => { expect(called).toBeTruthy(); }); - it(`should hide the dialog when response is given`, () => { - controller.show(); - spyOn(controller, 'hide'); - controller.respond('answer'); - - expect(controller.hide).toHaveBeenCalledWith('answer'); - }); - it(`should not hide the dialog when false is returned from response handler`, () => { controller.show(() => false); spyOn(controller, 'hide'); @@ -46,12 +38,13 @@ describe('Component vnDialog', () => { }); describe('hide()', () => { - it(`should do nothing if it's already hidden`, () => { - controller.onResponse = () => {}; - spyOn(controller, 'onResponse'); + it(`should resolve the promise returned by show`, () => { + let resolved = true; + controller.show().then(() => resolved = true); controller.hide(); + $scope.$apply(); - expect(controller.onResponse).not.toHaveBeenCalledWith(); + expect(resolved).toBeTruthy(); }); }); @@ -94,7 +87,7 @@ describe('Component vnDialog', () => { expect(controller.onAccept).toHaveBeenCalledWith({$response: 'accept'}); }); - it(`should resolve the promise returned by show() with response when hidden`, () => { + it(`should resolve the promise returned by show() with response`, () => { let response; controller.show().then(res => response = res); controller.respond('response'); diff --git a/front/core/components/dialog/style.scss b/front/core/components/dialog/style.scss index 9461a0063..2f3d9a028 100644 --- a/front/core/components/dialog/style.scss +++ b/front/core/components/dialog/style.scss @@ -36,7 +36,7 @@ background-color: transparent; border: none; border-radius: .1em; - color: $color-main; + color: $color-button; font-family: vn-font-bold; padding: .7em; margin: -0.7em; diff --git a/front/core/components/drop-down/index.js b/front/core/components/drop-down/index.js index 163553aeb..25376841c 100644 --- a/front/core/components/drop-down/index.js +++ b/front/core/components/drop-down/index.js @@ -5,6 +5,7 @@ import template from './index.html'; import ArrayModel from '../array-model/array-model'; import CrudModel from '../crud-model/crud-model'; import {mergeWhere} from 'vn-loopback/util/filter'; +import focus from '../../lib/focus'; /** * @event select Thrown when model item is selected @@ -86,9 +87,11 @@ export default class DropDown extends Popover { * @param {String} search The initial search term or %null */ show(parent, search) { - this._activeOption = -1; + if (this.shown) return; super.show(parent); + this._activeOption = -1; + this.list = this.popup.querySelector('.list'); this.ul = this.popup.querySelector('ul'); @@ -102,21 +105,25 @@ export default class DropDown extends Popover { this.search = search; this.buildList(); - let input = this.popup.querySelector('input'); - setTimeout(() => input.focus()); + focus(this.popup.querySelector('input')); } - onClose() { + hide() { + if (!this.shown) return; + super.hide(); + this.document.removeEventListener('keydown', this.docKeyDownHandler); this.docKeyDownHandler = null; this.list.removeEventListener('scroll', this.listScrollHandler); this.listScrollHandler = null; + } + onClose() { + this.destroyList(); this.list = null; this.ul = null; - this.destroyList(); super.onClose(); } diff --git a/front/core/components/field/index.html b/front/core/components/field/index.html index 8d12ddd77..d614d157f 100644 --- a/front/core/components/field/index.html +++ b/front/core/components/field/index.html @@ -28,8 +28,7 @@ ng-transclude="append" class="append"> -
-
+
diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss index add3a3228..a56b8e7dd 100644 --- a/front/core/components/field/style.scss +++ b/front/core/components/field/style.scss @@ -2,6 +2,7 @@ .vn-field { display: inline-block; + box-sizing: border-box; width: 100%; & > .container { @@ -22,7 +23,7 @@ top: 18px; line-height: 20px; pointer-events: none; - color: $color-font-secondary; + color: $color-font-bg-marginal; transition-property: top, color, font-size; transition-duration: 400ms; transition-timing-function: cubic-bezier(.4, 0, .2, 1); @@ -67,6 +68,7 @@ } & > input { position: relative; + color: $color-font; &[type=time], &[type=date], @@ -121,12 +123,13 @@ & > .icons { display: flex; align-items: center; - color: $color-font-secondary; + color: $color-font-bg-marginal; } & > .prepend > prepend, & > .append > append, & > .icons { display: flex; + align-items: center; & > vn-icon { font-size: 24px; @@ -159,7 +162,7 @@ } &.focus { height: 2px; - background-color: $color-main; + background-color: $color-primary; left: 50%; width: 0; transition-property: width, left, background-color; @@ -190,13 +193,49 @@ } } } + &.standout { + border-radius: .1em; + background-color: rgba(255, 255, 255, .1); + padding: 0 12px; + transition-property: background-color, color; + transition-duration: 200ms; + transition-timing-function: ease-in-out; + + & > .container { + & > .underline { + display: none; + } + & > .infix > .control > * { + color: $color-font-dark; + } + & > .prepend, + & > .append, + & > .icons { + color: $color-font-bg-dark-marginal; + } + } + &.focused { + background-color: $color-bg-panel; + + & > .container { + & > .infix > .control > * { + color: $color-font; + } + & > .prepend, + & > .append, + & > .icons { + color: $color-font-bg-marginal; + } + } + } + } &.not-empty, &.focused, &.invalid { & > .container > .infix { & > label { top: 5px; - color: $color-main; + color: $color-primary; padding: 0; font-size: 12px; } diff --git a/front/core/components/icon-button/style.scss b/front/core/components/icon-button/style.scss index 1126c5e6d..d59980a62 100644 --- a/front/core/components/icon-button/style.scss +++ b/front/core/components/icon-button/style.scss @@ -2,7 +2,7 @@ .vn-icon-button { @extend %clickable-light; - color: $color-main; + color: $color-button; & > button { padding: .2em !important; diff --git a/front/core/components/index.js b/front/core/components/index.js index bc19db642..0ebd03420 100644 --- a/front/core/components/index.js +++ b/front/core/components/index.js @@ -41,6 +41,7 @@ import './list'; import './popover'; import './popup'; import './radio'; +import './slot'; import './submit'; import './table'; import './td-editable'; diff --git a/front/core/components/list/style.scss b/front/core/components/list/style.scss index 0786cacf8..6f12ce7c6 100644 --- a/front/core/components/list/style.scss +++ b/front/core/components/list/style.scss @@ -1,45 +1,102 @@ @import "./effects"; +/* +ul.menu { + list-style-type: none; + padding: 0; + padding-top: $spacing-md; + margin: 0; + font-size: inherit; + & > li > a { + @extend %clickable; + display: block; + color: inherit; + padding: .6em 2em; + } +} +*/ + +vn-list, .vn-list { + display: block; max-width: $width-sm; margin: 0 auto; + padding: 0; + list-style-type: none; - a.vn-list-item { - @extend %clickable; + vn-list, + .vn-list { + vn-item, + .vn-item { + padding-left: $spacing-lg; + } } - .vn-list-item { - border-bottom: $border-thin-light; - display: block; - text-decoration: none; - color: inherit; - - & > vn-horizontal { + &.separated { + vn-item, + .vn-item { + border-bottom: $border-thin-light; padding: $spacing-md; - - & > vn-one { - overflow: hidden; + + &:last-child { + border-bottom: none; } - & > .buttons { - align-items: center; + } + } +} + +vn-item, +.vn-item { + @extend %clickable; + display: flex; + align-items: center; + color: inherit; + padding: $spacing-sm $spacing-md; + text-decoration: none; + min-height: 40px; + box-sizing: border-box; + + &.separated { + border-bottom: $border-thin-light; - vn-icon-button { - opacity: .4; - margin-left: .5em; - transition: opacity 250ms ease-out; - padding: 0; - font-size: 1.2em; - - &:hover { - opacity: 1; - } + &:last-child { + border-bottom: none; + } + } + &.active { + @extend %active; + } + & > vn-item-section { + overflow: hidden; + flex: 1; + + &[avatar] { + display: flex; + flex: none; + align-items: center; + margin-right: $spacing-md; + + & > .vn-icon { + font-size: 1.2em; + } + } + &[side] { + display: flex; + flex: none; + align-items: center; + + & > .vn-button { + opacity: .4; + margin-left: .5em; + transition: opacity 250ms ease-out; + padding: 0; + font-size: 1.05em; + + &:hover { + opacity: 1; } } } } - vn-empty-rows { - display: block; - text-align: center; - padding: 1.5em; - box-sizing: border-box; - } -} \ No newline at end of file +} + + diff --git a/front/core/components/popup/index.js b/front/core/components/popup/index.js index dfafcd7d4..b6902428c 100644 --- a/front/core/components/popup/index.js +++ b/front/core/components/popup/index.js @@ -40,6 +40,11 @@ export default class Popup extends Component { if (this.shown) return; this._shown = true; + if (this.closeTimeout) { + this.$timeout.cancel(this.closeTimeout); + this.onClose(); + } + let linkFn = this.$compile(this.template); this.$contentScope = this.$.$new(); this.popup = linkFn(this.$contentScope, null, @@ -60,9 +65,9 @@ export default class Popup extends Component { this.deregisterCallback = this.$transitions.onStart({}, () => this.hide()); - this.$timeout.cancel(this.transitionTimeout); - this.transitionTimeout = this.$timeout(() => { - this.transitionTimeout = null; + this.$timeout.cancel(this.showTimeout); + this.showTimeout = this.$timeout(() => { + this.showTimeout = null; classList.add('shown'); }, 10); @@ -78,15 +83,13 @@ export default class Popup extends Component { this.document.removeEventListener('keydown', this.keyDownHandler); this.keyDownHandler = null; - if (this.deregisterCallback) { - this.deregisterCallback(); - this.deregisterCallback = null; - } + this.deregisterCallback(); + this.deregisterCallback = null; this.popup.classList.remove('shown'); - this.$timeout.cancel(this.transitionTimeout); - this.transitionTimeout = this.$timeout( + this.$timeout.cancel(this.closeTimeout); + this.closeTimeout = this.$timeout( () => this.onClose(), 200); this.lastEvent = null; @@ -95,7 +98,7 @@ export default class Popup extends Component { } onClose() { - this.transitionTimeout = null; + this.closeTimeout = null; this.document.body.removeChild(this.popup); this.$contentScope.$destroy(); diff --git a/front/core/components/radio/style.scss b/front/core/components/radio/style.scss index 787c0986e..2ee037e65 100644 --- a/front/core/components/radio/style.scss +++ b/front/core/components/radio/style.scss @@ -9,7 +9,7 @@ } } &.checked > .btn { - border-color: $color-main; + border-color: $color-button; & > .mark { position: absolute; @@ -19,7 +19,7 @@ transform: translate(-50%, -50%); width: 10px; height: 10px; - background-color: $color-main; + background-color: $color-button; } } &.disabled.checked > .btn > .mark { diff --git a/front/core/components/range/style.scss b/front/core/components/range/style.scss index a370b4c39..6898f8cda 100644 --- a/front/core/components/range/style.scss +++ b/front/core/components/range/style.scss @@ -5,7 +5,7 @@ -webkit-appearance: none; margin-top: -5px; border-radius: 50%; - background: $color-main; + background: $color-button; border: none; height: 12px; width: 12px; @@ -15,7 +15,7 @@ transition-timing-function: ease-out; } &:focus::#{$thumb-selector} { - box-shadow: 0 0 0 10px rgba($color-main, .2); + box-shadow: 0 0 0 10px rgba($color-button, .2); } &:active::#{$thumb-selector} { transform: scale(1.5); @@ -29,7 +29,7 @@ width: 100%; height: 3px; cursor: inherit; - background: $color-secondary; + background: $color-marginal; border-radius: 2px; border: none; } @@ -40,7 +40,7 @@ font-size: 12px; &.main { - color: $color-main; + color: $color-button; } &.min-label { float: left; diff --git a/front/core/components/searchbar/searchbar.html b/front/core/components/searchbar/searchbar.html index 069a9411c..d6f4720f2 100644 --- a/front/core/components/searchbar/searchbar.html +++ b/front/core/components/searchbar/searchbar.html @@ -1,14 +1,26 @@
+
+ + + + {{param.chip}} + +
this.onStateChange()); + constructor($element, $) { + super($element, $); + this.searchState = '.'; - this._filter = null; - this.autoLoad = false; + let criteria = {}; + this.deregisterCallback = this.$transitions.onSuccess( + criteria, () => this.onStateChange()); } $postLink() { - if (this.filter === null) - this.onStateChange(); + this.onStateChange(); } - set filter(value) { - this._filter = value; - this.$state.go('.', {q: JSON.stringify(value)}, {location: 'replace'}); - } - - get filter() { - return this._filter; - } - - onStateChange() { - this._filter = null; - - if (this.$state.params.q) { - try { - this._filter = JSON.parse(this.$state.params.q); - } catch (e) { - console.error(e); - } - } - - this.doSearch(); + $onDestroy() { + this.deregisterCallback(); } get shownFilter() { - return this._filter != null ? this._filter : this.suggestedFilter; + return this.filter != null + ? this.filter + : this.suggestedFilter; + } + + onStateChange() { + if (this.$state.is(this.searchState)) { + if (this.$state.params.q) { + try { + this.filter = JSON.parse(this.$state.params.q); + } catch (e) { + console.error(e); + } + } else + this.filter = null; + + focus(this.element.querySelector('vn-textfield input')); + } else + this.filter = null; + + this.toBar(this.filter); } openPanel(event) { @@ -88,21 +81,143 @@ export default class Controller extends Component { onPanelSubmit(filter) { this.$.popover.hide(); filter = compact(filter); - this.filter = filter != null ? filter : {}; - - let element = this.element.querySelector('vn-textfield input'); - element.select(); - element.focus(); + filter = filter != null ? filter : {}; + this.doSearch(filter); } onSubmit() { - this.filter = this.getObjectFromString(this.searchString); + this.doSearch(this.fromBar()); + } + + removeParam(index) { + this.params.splice(index, 1); + this.doSearch(this.fromBar()); + } + + get searchString() { + return this._searchString; + } + + set searchString(value) { + this._searchString = value; + if (value == null) this.params = []; + } + + doSearch(filter) { + let opts = this.$state.is(this.searchState) + ? {location: 'replace'} : null; + this.$state.go(this.searchState, + {q: JSON.stringify(filter)}, opts); + } + + fromBar() { + let filter = {}; + + if (this.searchString) + filter.search = this.searchString; + + if (this.params) { + for (let param of this.params) + filter[param.key] = param.value; + } + + return filter; + } + + toBar(filter) { + this.params = []; + this.searchString = filter && filter.search; + if (!filter) return; + + let keys = Object.keys(filter); + keys.forEach(key => { + if (key == 'search') return; + let value = filter[key]; + let chip; + + if (typeof value == 'string' + && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) + value = new Date(value); + + switch (typeof value) { + case 'boolean': + chip = `${value ? '' : 'not '}${key}`; + break; + case 'number': + case 'string': + chip = `${key}: ${value}`; + break; + default: + if (value instanceof Date) { + let format = 'yyyy-MM-dd'; + if (value.getHours() || value.getMinutes()) + format += ' HH:mm'; + chip = `${key}: ${this.$filter('date')(value, format)}`; + } else + chip = key; + } + + this.params.push({chip, key, value}); + }); + } +} + +ngModule.vnComponent('vnSearchbar', { + controller: Controller, + template: require('./searchbar.html'), + bindings: { + searchState: '@?', + filter: ' this.onStateChange()); + + this.fetchFilter(); + } + + $postLink() { + if (this.filter !== null) + this.doSearch(); + } + + $onDestroy() { + this.deregisterCallback(); + } + + fetchFilter() { + if (this.$state.params.q) { + try { + this.filter = JSON.parse(this.$state.params.q); + } catch (e) { + console.error(e); + } + } else + this.filter = null; + } + + onStateChange() { + this.fetchFilter(); + this.doSearch(); } doSearch() { - this.searchString = this.getStringFromObject(this.shownFilter); - - let filter = this._filter; + let filter = this.filter; if (filter == null && this.autoload) filter = {}; @@ -141,94 +256,17 @@ export default class Controller extends Component { exprBuilder(param, value) { return {[param]: value}; } - - /** - * Finds pattern key:value or key:(extra value) and passes it to object. - * - * @param {String} searchString The search string - * @return {Object} The parsed object - */ - getObjectFromString(searchString) { - let result = {}; - if (searchString) { - let regex = /((([\w_]+):([\w_]+))|([\w_]+):\(([\w_ ]+)\))/gi; - let findPattern = searchString.match(regex); - let remnantString = searchString.replace(regex, '').trim(); - if (findPattern) { - for (let i = 0; i < findPattern.length; i++) { - let aux = findPattern[i].split(':'); - let property = aux[0]; - let value = aux[1].replace(/\(|\)/g, ''); - result[property] = value.trim(); - } - } - if (remnantString) - result.search = remnantString; - } - return result; - } - - /** - * Passes an object to pattern key:value or key:(extra value). - * - * @param {Object} searchObject The search object - * @return {String} The passed string - */ - getStringFromObject(searchObject) { - let search = []; - - if (searchObject) { - let keys = Object.keys(searchObject); - keys.forEach(key => { - if (key == 'search') return; - - let value = searchObject[key]; - let valueString; - - if (typeof value === 'string' && value.indexOf(' ') !== -1) - valueString = `(${value})`; - else if (value instanceof Date) - valueString = value.toJSON(); - else { - switch (typeof value) { - case 'number': - case 'string': - case 'boolean': - valueString = `${value}`; - } - } - - if (valueString) - search.push(`${key}:${valueString}`); - }); - - if (searchObject.search) - search.unshift(searchObject.search); - } - - return search.length ? search.join(' ') : ''; - } - - $onDestroy() { - this.deregisterCallback(); - } } -Controller.$inject = ['$element', '$scope', '$compile', '$state', '$transitions']; +AutoSearch.$inject = ['$state', '$transitions']; -ngModule.component('vnSearchbar', { - template: require('./searchbar.html'), +ngModule.vnComponent('vnAutoSearch', { + controller: AutoSearch, bindings: { - filter: ' .search-param { + color: rgba(0, 0, 0, .6); + background-color: rgba(0, 0, 0, .1); + padding: .1em .4em; + margin-left: .2em; + display: inline-block; + border-radius: .8em; + max-width: 18em; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + & > vn-icon { + font-size: inherit; + vertical-align: middle; + cursor: pointer; + border-radius: 50%; + + &:hover { + color: rgba(0, 0, 0, .8); + } + } + } + } } .search-panel { diff --git a/front/core/components/slot/index.js b/front/core/components/slot/index.js new file mode 100644 index 000000000..1747ed93f --- /dev/null +++ b/front/core/components/slot/index.js @@ -0,0 +1,81 @@ +import ngModule from '../../module'; +import './portal'; +import './style.scss'; + +export class Slot { + constructor($element, vnSlotService) { + this.$element = $element; + this.vnSlotService = vnSlotService; + this.$content = null; + } + + $onDestroy() { + this.unregister(); + } + + set name(value) { + this.unregister(); + this._name = value; + this.vnSlotService.slots[value] = this; + } + + get name() { + return this._name; + } + + unregister() { + if (this.name) + this.vnSlotService.slots[this.name] = undefined; + } + + setContent($content) { + if (this.$content) { + this.$content.detach(); + this.$content = null; + } + + this.$content = $content; + if (this.$content) this.$element.append($content); + this.$element[0].style.display = $content ? 'block' : 'none'; + } +} +Slot.$inject = ['$element', 'vnSlotService']; + +ngModule.vnComponent('vnSlot', { + controller: Slot, + bindings: { + name: '@?' + } +}); + +export class SlotService { + constructor() { + this.stacks = {}; + this.slots = {}; + } + + push(slot, $transclude) { + if (!this.stacks[slot]) this.stacks[slot] = []; + this.stacks[slot].unshift($transclude); + this.refreshContent(slot); + } + + pop(slot) { + let $content = this.stacks[slot].shift(); + this.refreshContent(slot); + if ($content && typeof $content == 'object') + $content.remove(); + } + + refreshContent(slot) { + if (!this.slots[slot]) return; + let $content = this.stacks[slot][0]; + if (typeof $content == 'function') { + $content(clone => { + $content = this.stacks[slot][0] = clone; + }); + } + this.slots[slot].setContent($content); + } +} +ngModule.service('vnSlotService', SlotService); diff --git a/front/core/components/slot/portal.js b/front/core/components/slot/portal.js new file mode 100644 index 000000000..f4dbecb09 --- /dev/null +++ b/front/core/components/slot/portal.js @@ -0,0 +1,28 @@ +import ngModule from '../../module'; + +/** + * Component used to fill slots with content. + */ +export default class Portal { + constructor($transclude, vnSlotService) { + this.$transclude = $transclude; + this.vnSlotService = vnSlotService; + } + + $postLink() { + this.vnSlotService.push(this.slot, this.$transclude); + } + + $onDestroy() { + this.vnSlotService.pop(this.slot); + } +} +Portal.$inject = ['$transclude', 'vnSlotService']; + +ngModule.component('vnPortal', { + controller: Portal, + transclude: true, + bindings: { + slot: '@' + } +}); diff --git a/front/core/components/slot/style.scss b/front/core/components/slot/style.scss new file mode 100644 index 000000000..825aad085 --- /dev/null +++ b/front/core/components/slot/style.scss @@ -0,0 +1,3 @@ +vn-slot { + display: block; +} \ No newline at end of file diff --git a/front/core/components/spinner/spinner.html b/front/core/components/spinner/spinner.html index b6a3af8be..440e47445 100644 --- a/front/core/components/spinner/spinner.html +++ b/front/core/components/spinner/spinner.html @@ -6,6 +6,7 @@ cy="50" r="20" fill="none" + stroke="currentColor" stroke-miterlimit="10"> diff --git a/front/core/components/spinner/style.scss b/front/core/components/spinner/style.scss index 3be908caf..eb39f64e8 100644 --- a/front/core/components/spinner/style.scss +++ b/front/core/components/spinner/style.scss @@ -4,6 +4,7 @@ vn-spinner { display: inline-block; min-height: 28px; min-width: 28px; + color: $color-main; & > .loader { position: relative; @@ -29,7 +30,6 @@ vn-spinner { margin: auto; & > .path { - stroke: $color-main; stroke-dasharray: 1, 200; stroke-dashoffset: 0; stroke-linecap: square; diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index a3fd4513b..871ecc381 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -3,8 +3,8 @@ vn-table { display: block; - overflow: auto; width: 100%; + // overflow: auto; } .vn-table { width: 100%; diff --git a/front/core/components/toggle/style.scss b/front/core/components/toggle/style.scss index af3dc3ae5..31769d2a5 100644 --- a/front/core/components/toggle/style.scss +++ b/front/core/components/toggle/style.scss @@ -40,10 +40,10 @@ background-color: rgba(0, 0, 0, .1); } &.checked > .btn { - border-color: $color-main; + border-color: $color-button; & > .focus-mark { - background-color: rgba($color-main, .15); + background-color: rgba($color-button, .15); } } &.disabled { diff --git a/front/core/components/wday-picker/style.scss b/front/core/components/wday-picker/style.scss index c6899ad6a..be610c733 100644 --- a/front/core/components/wday-picker/style.scss +++ b/front/core/components/wday-picker/style.scss @@ -20,7 +20,7 @@ background-color: rgba(0, 0, 0, .05); &.marked { - background: $color-main; + background: $color-button; color: $color-font-dark; } } diff --git a/front/core/directives/id.js b/front/core/directives/id.js index 693606b0c..8230527d6 100644 --- a/front/core/directives/id.js +++ b/front/core/directives/id.js @@ -12,14 +12,23 @@ export function directive() { restrict: 'A', link: function($scope, $element, $attrs) { let id = kebabToCamel($attrs.vnId); - let $ctrl = $element[0].$ctrl - ? $element[0].$ctrl - : $element.controller($element[0].tagName.toLowerCase()); if (!id) throw new Error(`vnId: Attribute can't be null`); - $scope[id] = $ctrl || $element[0]; + let $ctrl = $element[0].$ctrl + ? $element[0].$ctrl + : $element.controller($element[0].tagName.toLowerCase()); + let ctrl = $ctrl || $element[0]; + + $scope[id] = ctrl; + + if (!$scope.hasOwnProperty('$ctrl')) { + while ($scope && !$scope.hasOwnProperty('$ctrl')) + $scope = Object.getPrototypeOf($scope); + + if ($scope) $scope[id] = ctrl; + } } }; } diff --git a/front/core/lib/component.js b/front/core/lib/component.js index 979420b22..b9f04dba6 100644 --- a/front/core/lib/component.js +++ b/front/core/lib/component.js @@ -107,6 +107,7 @@ function runFn( $compile, $filter, $interpolate, + $window, vnApp) { Object.assign(Component.prototype, { $translate, @@ -119,6 +120,7 @@ function runFn( $compile, $filter, $interpolate, + $window, vnApp }); } @@ -133,6 +135,7 @@ runFn.$inject = [ '$compile', '$filter', '$interpolate', + '$window', 'vnApp' ]; diff --git a/front/core/lib/focus.js b/front/core/lib/focus.js new file mode 100644 index 000000000..8b997d920 --- /dev/null +++ b/front/core/lib/focus.js @@ -0,0 +1,16 @@ + +import isMobile from './is-mobile'; + +export default function focus(element) { + if (isMobile) return; + setTimeout(() => element.focus(), 10); +} + +export function select(element) { + if (isMobile) return; + setTimeout(() => { + element.focus(); + if (element.select) + element.select(); + }, 10); +} diff --git a/front/core/lib/index.js b/front/core/lib/index.js index 2682dfdf9..4d562ca05 100644 --- a/front/core/lib/index.js +++ b/front/core/lib/index.js @@ -2,8 +2,9 @@ import './module-loader'; import './crud'; import './copy'; import './equals'; +import './focus'; +import './get-main-route'; import './modified'; import './key-codes'; import './http-error'; import './user-error'; -import './get-main-route'; diff --git a/front/core/module.js b/front/core/module.js index 33eb68c24..0c52fd565 100644 --- a/front/core/module.js +++ b/front/core/module.js @@ -1,9 +1,6 @@ import {ng, ngDeps} from './vendor'; import {camelToKebab} from './lib/string'; -const ngModule = ng.module('vnCore', ngDeps); -export default ngModule; - /** * Acts like native Module.component() function but merging component options * with parent component options. This method establishes the $options property @@ -17,7 +14,7 @@ export default ngModule; * @param {Object} options The component options * @return {angularModule} The same angular module */ -ngModule.vnComponent = function(name, options) { +function vnComponent(name, options) { let controller = options.controller; let parent = Object.getPrototypeOf(controller); let parentOptions = parent.$options || {}; @@ -57,10 +54,21 @@ ngModule.vnComponent = function(name, options) { controller.$classNames = classNames; return this.component(name, mergedOptions); +} + +const ngModuleFn = ng.module; + +ng.module = function(...args) { + let ngModule = ngModuleFn.apply(this, args); + ngModule.vnComponent = vnComponent; + return ngModule; }; -config.$inject = ['$translateProvider', '$translatePartialLoaderProvider']; -export function config($translateProvider, $translatePartialLoaderProvider) { +const ngModule = ng.module('vnCore', ngDeps); +export default ngModule; + +config.$inject = ['$translateProvider', '$translatePartialLoaderProvider', '$animateProvider']; +export function config($translateProvider, $translatePartialLoaderProvider, $animateProvider) { // For CSS browser targeting document.documentElement.setAttribute('data-browser', navigator.userAgent); @@ -91,5 +99,8 @@ export function config($translateProvider, $translatePartialLoaderProvider) { return langAliases[locale]; return fallbackLang; }); + + $animateProvider.customFilter( + node => node.tagName == 'UI-VIEW'); } ngModule.config(config); diff --git a/front/core/services/interceptor.js b/front/core/services/interceptor.js index 448b70a34..b7cf3a0ec 100644 --- a/front/core/services/interceptor.js +++ b/front/core/services/interceptor.js @@ -13,11 +13,15 @@ function interceptor($q, vnApp, vnToken, $translate) { vnApp.pushLoader(); if (config.url.charAt(0) !== '/' && apiPath) - config.url = `${apiPath}/${config.url}`; + config.url = `${apiPath}${config.url}`; if (vnToken.token) config.headers.Authorization = vnToken.token; if ($translate.use()) config.headers['Accept-Language'] = $translate.use(); + if (config.filter) { + if (!config.params) config.params = {}; + config.params.filter = config.filter; + } return config; }, diff --git a/front/core/styles/global.scss b/front/core/styles/global.scss index ff49516dc..8b3d465f1 100644 --- a/front/core/styles/global.scss +++ b/front/core/styles/global.scss @@ -40,4 +40,8 @@ button { a { color: $color-font-link; text-decoration: none; +} +.ng-leave, +.ng-enter { + transition: none; } \ No newline at end of file diff --git a/front/core/styles/variables.scss b/front/core/styles/variables.scss index 454bc6f7c..cd918342c 100644 --- a/front/core/styles/variables.scss +++ b/front/core/styles/variables.scss @@ -19,27 +19,36 @@ $spacing-xs: 4px; $spacing-sm: 8px; $spacing-md: 16px; $spacing-lg: 32px; -$spacing-xl: 100px; +$spacing-xl: 70px; // Light theme -$color-header: #3d3d3d; -$color-bg: #e5e5e5; -$color-bg-dark: #3d3d3d; +$color-primary: #f7931e; +$color-secondary: $color-primary; + $color-font: #222; $color-font-light: #555; $color-font-secondary: #9b9b9b; $color-font-dark: white; -$color-font-bg: rgba(0, 0, 0, .7); $color-font-link: #005a9a; -$color-active: #3d3d3d; -$color-active-font: white; +$color-font-bg: rgba(0, 0, 0, .7); +$color-font-bg-marginal: rgba(0, 0, 0, .4); +$color-font-bg-dark: rgba(255, 255, 255, .7); +$color-font-bg-dark-marginal: rgba(255, 255, 255, .4); + +$color-header: darken($color-primary, 5%); +$color-menu-header: #3d3d3d; +$color-bg: #e5e5e5; +$color-bg-dark: #3d3d3d; +$color-active: $color-primary; +$color-active-font: $color-font-dark; $color-bg-panel: white; -$color-main: #f7931e; -$color-secondary: #ccc; +$color-main: $color-primary; +$color-marginal: #ccc; $color-success: #a3d131; $color-notice: #32b1ce; $color-alert: #f42121; +$color-button: $color-secondary; $color-spacer: rgba(0, 0, 0, .3); $color-spacer-light: rgba(0, 0, 0, .12); @@ -78,7 +87,7 @@ $color-active: #666; $color-active-font: white; $color-bg-panel: #3c3b3b; $color-main: #f7931e; -$color-secondary: #ccc; +$color-marginal: #ccc; $color-success: #a3d131; $color-notice: #32b1ce; $color-alert: #f42121; diff --git a/front/core/vendor.js b/front/core/vendor.js index 0cdae4e81..8cec57f4f 100644 --- a/front/core/vendor.js +++ b/front/core/vendor.js @@ -2,6 +2,7 @@ import '@babel/polyfill'; import * as ng from 'angular'; export {ng}; +import 'angular-animate'; import 'angular-translate'; import 'angular-translate-loader-partial'; import '@uirouter/angularjs'; @@ -9,6 +10,7 @@ import 'mg-crud'; import 'oclazyload'; export const ngDeps = [ + 'ngAnimate', 'pascalprecht.translate', 'ui.router', 'mgCrud', diff --git a/front/package-lock.json b/front/package-lock.json index 9d71d20cc..f546f6c65 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -31,6 +31,11 @@ "resolved": "https://registry.npmjs.org/angular/-/angular-1.7.5.tgz", "integrity": "sha512-760183yxtGzni740IBTieNuWLtPNAoMqvmC0Z62UoU0I3nqk+VJuO3JbQAXOyvo3Oy/ZsdNQwrSTh/B0OQZjNw==" }, + "angular-animate": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.7.8.tgz", + "integrity": "sha512-bINtzizq7TbJzfVrDpwLfTxVl0Qd7fRNWFb5jKYI1vaFZobQNX/QONXlLow6ySsDbZ6eLECycB7mvWtfh1YYaw==" + }, "angular-translate": { "version": "2.18.1", "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.1.tgz", diff --git a/front/package.json b/front/package.json index e17dbd08c..1eb3a8b8e 100644 --- a/front/package.json +++ b/front/package.json @@ -12,6 +12,7 @@ "@babel/polyfill": "^7.2.5", "@uirouter/angularjs": "^1.0.20", "angular": "^1.7.5", + "angular-animate": "^1.7.8", "angular-translate": "^2.18.1", "angular-translate-loader-partial": "^2.18.1", "js-yaml": "^3.13.1", diff --git a/front/salix/components/app/app.html b/front/salix/components/app/app.html index d6ac05d7e..89e67e0ad 100644 --- a/front/salix/components/app/app.html +++ b/front/salix/components/app/app.html @@ -1,29 +1,4 @@ - - - - -
- {{$ctrl.$state.current.description}} -
- - - - -
-
- -
+ + \ No newline at end of file diff --git a/front/salix/components/app/app.js b/front/salix/components/app/app.js index edf482712..1f8cdb46e 100644 --- a/front/salix/components/app/app.js +++ b/front/salix/components/app/app.js @@ -1,5 +1,6 @@ import ngModule from '../../module'; import './style.scss'; +import Component from 'core/lib/component'; /** * The main graphical application component. @@ -7,28 +8,21 @@ import './style.scss'; * @property {SideMenu} leftMenu The left menu, if it's present * @property {SideMenu} rightMenu The left menu, if it's present */ -export default class App { - constructor($, $state, vnApp) { - Object.assign(this, { - $, - $state, - vnApp - }); - } - +export default class App extends Component { $postLink() { this.vnApp.logger = this; } - $onDestroy() { - this.vnApp.logger = null; - } - - get showTopbar() { + get showLayout() { let state = this.$state.current.name; return state && state != 'login'; } + $onDestroy() { + this.deregisterCallback(); + this.vnApp.logger = null; + } + showMessage(message) { this.$.snackbar.show({message: message}); } @@ -41,9 +35,8 @@ export default class App { this.$.snackbar.showError({message: message}); } } -App.$inject = ['$scope', '$state', 'vnApp']; -ngModule.component('vnApp', { +ngModule.vnComponent('vnApp', { template: require('./app.html'), controller: App }); diff --git a/front/salix/components/app/style.scss b/front/salix/components/app/style.scss index 530524773..bf47218ae 100644 --- a/front/salix/components/app/style.scss +++ b/front/salix/components/app/style.scss @@ -1,99 +1,21 @@ @import "variables"; vn-app { - height: inherit; display: block; + height: inherit; - & > vn-topbar { - position: fixed; - top: 0; - left: 0; - width: 100%; - z-index: 10; - box-shadow: 0 .1em .2em $color-shadow; - height: $topbar-height; - padding: .4em; - - & > header { - & > * { - padding: .3em; - } - & > .logo > img { - height: 1.4em; - display: block; - } - & > .show-menu { - display: none; - font-size: 1.8em; - cursor: pointer; - - &:hover { - color: $color-main; - } - } - & > .main-title { - font-size: 1.6em; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - padding-left: .6em; - } - & > vn-spinner { - padding: 0 .4em; - } - & > vn-main-menu { - flex: 1; - } - } - } - & > .main-view { + ui-view { + display: block; box-sizing: border-box; - height: inherit; - - &.padding { - padding-top: $topbar-height; - } - .content-block { - box-sizing: border-box; - padding: $spacing-md; - height: inherit; - } - vn-main-block { - display: block; - margin: 0 auto; - padding-left: $menu-width; - height: 100% - - } - .main-with-right-menu { - padding-right: $menu-width; - - @media screen and (max-width: 800px) { - padding-right: 0; - } - } - } - @media screen and (max-width: $mobile-width) { - & > vn-topbar > header { - & > .logo { - display: none; - } - & > .show-menu { - display: block; - } + &.ng-enter { + transition: all 200ms ease-out; + transform: translate3d(-2em, 0, 0); + opacity: 0; } - & > .main-view { - .content-block { - margin-left: 0; - margin-right: 0; - } - vn-main-block { - padding-left: 0; - } - .main-with-right-menu { - padding-right: 0; - } + &.ng-enter.ng-enter-active { + transform: translate3d(0, 0, 0); + opacity: 1; } } } diff --git a/front/salix/components/descriptor/style.scss b/front/salix/components/descriptor/style.scss index 16bc23b28..af719cc0d 100644 --- a/front/salix/components/descriptor/style.scss +++ b/front/salix/components/descriptor/style.scss @@ -50,7 +50,7 @@ & > vn-icon { padding: $spacing-sm; - color: $color-secondary; + color: $color-marginal; font-size: 1.5em; &.bright { diff --git a/front/salix/components/home/home.html b/front/salix/components/home/home.html index 47307d22e..b3fc02d0d 100644 --- a/front/salix/components/home/home.html +++ b/front/salix/components/home/home.html @@ -1,4 +1,4 @@ -
+
+ + +
+
+ {{$ctrl.$state.current.description}} +
+ + +
+ +
+ + + + +
+ +
    +
  • + + {{::mod.name}} +
  • +
+
+ + +
+ + + + + + + + + + {{::mod.name}} + + + + + \ No newline at end of file diff --git a/front/salix/components/layout/index.js b/front/salix/components/layout/index.js new file mode 100644 index 000000000..f386c5654 --- /dev/null +++ b/front/salix/components/layout/index.js @@ -0,0 +1,19 @@ +import ngModule from '../../module'; +import Component from 'core/lib/component'; +import './style.scss'; + +export class Layout extends Component { + constructor($element, $, vnModules) { + super($element, $); + this.modules = vnModules.get(); + } +} +Layout.$inject = ['$element', '$scope', 'vnModules']; + +ngModule.component('vnLayout', { + template: require('./index.html'), + controller: Layout, + require: { + app: '^vnApp' + } +}); diff --git a/front/salix/components/app/logo.svg b/front/salix/components/layout/logo.svg similarity index 100% rename from front/salix/components/app/logo.svg rename to front/salix/components/layout/logo.svg diff --git a/front/salix/components/layout/style.scss b/front/salix/components/layout/style.scss new file mode 100644 index 000000000..da8ebfbed --- /dev/null +++ b/front/salix/components/layout/style.scss @@ -0,0 +1,121 @@ +@import "variables"; + +vn-layout { + & > vn-topbar { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 10; + box-shadow: 0 .1em .2em $color-shadow; + height: $topbar-height; + padding: 0 1em; + justify-content: space-between; + + & > .start { + flex: 1; + display: flex; + align-items: center; + overflow: hidden; + padding-right: 1em; + + & > .main-title { + font-size: 1.6em; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + padding-left: .4em; + } + & > vn-spinner { + padding: 0 .4em; + color: $color-font-dark; + } + } + & > vn-slot { + flex: auto; + } + & > .end { + flex: 1; + padding-left: 1em; + align-items: center; + justify-content: flex-end; + display: flex; + } + .vn-button { + color: inherit; + font-size: 1.05em; + padding: 0; + } + .show-menu { + display: none; + } + } + & > vn-side-menu > .menu { + display: flex; + flex-direction: column; + align-items: stretch; + + & > .header { + background-color: $color-menu-header; + padding: $spacing-md; + color: $color-font-dark; + + & > .logo > img { + width: 100%; + display: block; + } + } + & > vn-slot { + flex: 1; + overflow: auto; + } + } + &.left-menu { + & > vn-topbar { + left: $menu-width; + } + & > .main-view { + padding-left: $menu-width; + } + } + &.right-menu { + & > .main-view { + padding-right: $menu-width; + } + } + & > .main-view { + padding-top: $topbar-height; + } + ui-view { + height: inherit; + + & > * { + display: block; + padding: $spacing-md; + } + } + @media screen and (max-width: $mobile-width) { + & > vn-topbar { + & > .show-menu { + display: block; + } + } + &.left-menu { + & > vn-topbar { + left: 0; + } + & > .main-view { + padding-left: 0; + } + } + &.right-menu { + & > .main-view { + padding-right: 0; + } + } + ui-view > * { + padding-left: 0; + padding-right: 0; + } + } +} diff --git a/front/salix/components/left-menu/left-menu.html b/front/salix/components/left-menu/left-menu.html index 12cea49a3..73488a24b 100644 --- a/front/salix/components/left-menu/left-menu.html +++ b/front/salix/components/left-menu/left-menu.html @@ -1,17 +1,30 @@ -
    +
    • - - - {{::item.description}} + + + + + {{::item.description}} + + + + -
        + diff --git a/front/salix/components/left-menu/left-menu.js b/front/salix/components/left-menu/left-menu.js index 576dcc2df..92adb02aa 100644 --- a/front/salix/components/left-menu/left-menu.js +++ b/front/salix/components/left-menu/left-menu.js @@ -6,24 +6,42 @@ export default class LeftMenu { this.$element = $element; this.$timeout = $timeout; this.$state = $state; + this.aclService = aclService; this.deregisterCallback = $transitions.onSuccess({}, () => this.activateItem()); + this.source = 'main'; this._depth = 3; + } + $onInit() { + this.items = this.fetchItems(); + this.activateItem(); + } + + set depth(value) { + this._depth = value; + this.activateItem(); + } + + get depth() { + return this._depth; + } + + fetchItems() { let states = this.$state.router.stateRegistry.states; let moduleIndex = this.$state.current.data.moduleIndex; let moduleFile = window.routes[moduleIndex] || []; - let menu = moduleFile.menu || []; + let menu = moduleFile.menus && moduleFile.menus[this.source] || []; let items = []; - function addItem(items, item) { + let addItem = (items, item) => { let state = states[item.state]; if (!state) return; state = state.self; let acl = state.data.acl; - if (acl && !aclService.hasAny(acl)) + if (acl && !this.aclService.hasAny(acl)) return; items.push({ @@ -31,7 +49,7 @@ export default class LeftMenu { description: state.description, state: item.state }); - } + }; for (let item of menu) { if (item.state) @@ -52,17 +70,7 @@ export default class LeftMenu { } } - this.items = items; - this.activateItem(); - } - - set depth(value) { - this._depth = value; - this.activateItem(); - } - - get depth() { - return this._depth; + return items; } activateItem() { @@ -93,9 +101,8 @@ export default class LeftMenu { item.active = !item.active; this.$timeout(() => { - let element = this.$element[0].querySelector('a[class="expanded"]'); - if (element) - element.scrollIntoView(); + let element = this.$element[0].querySelector('a.expanded'); + if (element) element.scrollIntoView(); }); } @@ -109,6 +116,7 @@ ngModule.component('vnLeftMenu', { template: require('./left-menu.html'), controller: LeftMenu, bindings: { + source: '@?', depth: ' .vn-list { + padding: $spacing-md 0; - & > li { - list-style: none; - display: block; - - & > ul > li > a { - padding-left: 2em + & > li > .vn-item { + & > [side] > vn-icon[icon="keyboard_arrow_down"] { + transition: transform 200ms; } - } - - & > li > a { - @extend %clickable; - padding: .5em 1em; - display: block; - color: inherit; - - & > vn-icon:nth-child(1) { - vertical-align: middle; - margin-right: .4em - } - - & > vn-icon:nth-child(2) { - float: right; - margin-left: .4em - } - } - - & > li > a.active { - @extend %active; - } - - & > li > a.expanded { - & > vn-icon[icon="keyboard_arrow_down"] { - transition: all 0.2s; + &.expanded > [side] > vn-icon[icon="keyboard_arrow_down"] { transform: rotate(180deg); } } - - & > li > a.collapsed { - & > vn-icon[icon="keyboard_arrow_down"] { - transition: all 0.2s; - transform: rotate(0deg); - } - } } } diff --git a/front/salix/components/login/login.js b/front/salix/components/login/login.js index 401d4a4d9..efb5e02bb 100644 --- a/front/salix/components/login/login.js +++ b/front/salix/components/login/login.js @@ -14,6 +14,7 @@ export default class Controller { remember: true }); } + submit() { this.loading = true; this.vnAuth.login(this.user, this.password, this.remember) @@ -28,6 +29,7 @@ export default class Controller { throw err; }); } + focusUser() { this.$.userField.select(); this.$.userField.focus(); diff --git a/front/salix/components/main-menu/main-menu.html b/front/salix/components/main-menu/main-menu.html index c583ffe0c..9412de2dc 100644 --- a/front/salix/components/main-menu/main-menu.html +++ b/front/salix/components/main-menu/main-menu.html @@ -1,31 +1,15 @@ -
        -
        - {{$root.user.nickname}} -
        - - - - +
        + {{$root.user.nickname}}
        - -
          -
        • - - {{::mod.name}} -
        • -
        -
        + + \ No newline at end of file diff --git a/front/salix/components/main-menu/main-menu.js b/front/salix/components/main-menu/main-menu.js index 93ff955e7..2c4d22af5 100644 --- a/front/salix/components/main-menu/main-menu.js +++ b/front/salix/components/main-menu/main-menu.js @@ -2,12 +2,11 @@ import ngModule from '../../module'; import './style.scss'; export default class MainMenu { - constructor($, $http, vnAuth, vnModules) { + constructor($, $http, vnAuth) { Object.assign(this, { $, $http, - vnAuth, - modules: vnModules.get() + vnAuth }); } @@ -22,7 +21,7 @@ export default class MainMenu { }); } } -MainMenu.$inject = ['$scope', '$http', 'vnAuth', 'vnModules']; +MainMenu.$inject = ['$scope', '$http', 'vnAuth']; ngModule.component('vnMainMenu', { template: require('./main-menu.html'), diff --git a/front/salix/components/main-menu/style.scss b/front/salix/components/main-menu/style.scss index cd38472ab..0942a0a95 100644 --- a/front/salix/components/main-menu/style.scss +++ b/front/salix/components/main-menu/style.scss @@ -4,35 +4,30 @@ vn-main-menu { display: flex; align-items: center; - justify-content: flex-end; + justify-content: space-between; + box-sizing: border-box; - & > div { - display: flex; - align-items: center; - box-sizing: border-box; - - & > * { - transition: color 250ms ease-out; - } - & > #user { - vertical-align: middle; - font-weight: bold; - margin-right: .2em; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - cursor: pointer; - } - & > .vn-button { - font-size: 1.2em; - color: inherit; - padding: 0; - margin-left: .3em; - } - & > :hover { - color: $color-main; - opacity: 1; - } + & > * { + transition: color 250ms ease-out; + } + & > #user { + flex: 1; + vertical-align: middle; + font-weight: bold; + margin-right: .2em; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + } + & > .vn-button { + height: initial; + color: inherit; + padding: 0; + } + & > :hover { + color: $color-main; + opacity: 1; } } diff --git a/front/salix/components/module-card/index.js b/front/salix/components/module-card/index.js new file mode 100644 index 000000000..9131cc772 --- /dev/null +++ b/front/salix/components/module-card/index.js @@ -0,0 +1,29 @@ +import ngModule from '../../module'; +import Component from 'core/lib/component'; +import './style.scss'; + +/** + * Base class for module cards. + */ +export default class ModuleCard extends Component { + constructor($element, $) { + super($element, $); + this.element.classList.add('vn-module-card'); + } + + $onInit() { + this.reload(); + } + + /** + * Reloads the card data. Should be implemented or overriden by child + * classes. + */ + reload() { + throw new Error('ModuleCard::reload() method not implemented'); + } +} + +ngModule.vnComponent('vnModuleCard', { + controller: ModuleCard +}); diff --git a/front/salix/components/module-card/style.scss b/front/salix/components/module-card/style.scss new file mode 100644 index 000000000..0ae943efc --- /dev/null +++ b/front/salix/components/module-card/style.scss @@ -0,0 +1,5 @@ +@import "variables"; + +.vn-module-card { + padding: 0; +} \ No newline at end of file diff --git a/front/salix/components/module-main/index.html b/front/salix/components/module-main/index.html new file mode 100644 index 000000000..6e04f06d0 --- /dev/null +++ b/front/salix/components/module-main/index.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/front/salix/components/module-main/index.js b/front/salix/components/module-main/index.js new file mode 100644 index 000000000..39fbe42b8 --- /dev/null +++ b/front/salix/components/module-main/index.js @@ -0,0 +1,15 @@ +import ngModule from '../../module'; +import Component from 'core/lib/component'; +import './style.scss'; + +export default class ModuleMain extends Component { + constructor($element, $) { + super($element, $); + this.element.classList.add('vn-module-main'); + } +} + +ngModule.vnComponent('vnModuleMain', { + template: require('./index.html'), + controller: ModuleMain +}); diff --git a/front/salix/components/module-main/style.scss b/front/salix/components/module-main/style.scss new file mode 100644 index 000000000..d9bdbd940 --- /dev/null +++ b/front/salix/components/module-main/style.scss @@ -0,0 +1,5 @@ +@import "variables"; + +.vn-module-main { + padding: 0; +} \ No newline at end of file diff --git a/front/salix/components/side-menu/side-menu.js b/front/salix/components/side-menu/side-menu.js index dfac732a1..558a0961b 100644 --- a/front/salix/components/side-menu/side-menu.js +++ b/front/salix/components/side-menu/side-menu.js @@ -1,4 +1,5 @@ import ngModule from '../../module'; +import Component from 'core/lib/component'; import './style.scss'; /** @@ -7,15 +8,10 @@ import './style.scss'; * @property {String} side [left|right] The side where the menu is displayed * @property {Boolean} shown Whether the menu it's currently displayed (Only for small viewports) */ -export default class SideMenu { - constructor($, $element, $window, $transitions) { - Object.assign(this, { - $, - $element, - $window, - $transitions, - side: 'left' - }); +export default class SideMenu extends Component { + constructor($element, $) { + super($element, $); + this.side = 'left'; } $onInit() { @@ -23,18 +19,25 @@ export default class SideMenu { if (this.side == 'right') { this.menu.classList.add('right'); - this.app.rightMenu = this; + this.layout.rightMenu = this; + this.layout.element.classList.add('right-menu'); } else { this.menu.classList.add('left'); - this.app.leftMenu = this; + this.layout.leftMenu = this; + this.layout.element.classList.add('left-menu'); } } $onDestroy() { - if (this.side == 'right') - this.app.rightMenu = null; - else - this.app.leftMenu = null; + if (this.side == 'right') { + this.layout.rightMenu = null; + this.layout.element.classList.remove('right-menu'); + } else { + // this.layout.leftMenu = null; + this.layout.element.classList.remove('left-menu'); + } + + this.hide(); } onEscape(event) { @@ -50,6 +53,7 @@ export default class SideMenu { } show() { + if (this.shown) return; this.shown = true; this.handler = e => this.onEscape(e); this.$window.addEventListener('keydown', this.handler); @@ -57,12 +61,12 @@ export default class SideMenu { } hide() { + if (!this.shown) return; this.$window.removeEventListener('keydown', this.handler); this.stateHandler(); this.shown = false; } } -SideMenu.$inject = ['$scope', '$element', '$window', '$transitions']; ngModule.component('vnSideMenu', { template: require('./side-menu.html'), @@ -72,6 +76,6 @@ ngModule.component('vnSideMenu', { side: '@?' }, require: { - app: '^vnApp' + layout: '^vnLayout' } }); diff --git a/front/salix/components/side-menu/style.scss b/front/salix/components/side-menu/style.scss index 0054abfa7..6f1c22f14 100644 --- a/front/salix/components/side-menu/style.scss +++ b/front/salix/components/side-menu/style.scss @@ -1,5 +1,8 @@ @import "variables"; +vn-side-menu { + display: block; +} vn-side-menu > .menu { display: block; position: fixed; @@ -10,17 +13,17 @@ vn-side-menu > .menu { background-color: $color-bg-panel; box-shadow: 0 .1em .2em $color-shadow; overflow: auto; - top: $topbar-height; &.left { left: 0; + top: 0; } &.right { right: 0; + top: $topbar-height; } @media screen and (max-width: $mobile-width) { - top: 0; transition: transform 200ms ease-out; z-index: 15; @@ -28,6 +31,7 @@ vn-side-menu > .menu { transform: translateZ(0) translateX(-$menu-width); } &.right { + top: 0; transform: translateZ(0) translateX($menu-width); } &.shown { diff --git a/front/salix/components/summary/style.scss b/front/salix/components/summary/style.scss index 58a613088..f0d6ae038 100644 --- a/front/salix/components/summary/style.scss +++ b/front/salix/components/summary/style.scss @@ -59,4 +59,5 @@ .vn-popup .summary { border: none; box-shadow: none; + margin: 0; } diff --git a/front/salix/components/topbar/style.scss b/front/salix/components/topbar/style.scss index dc5273dbf..d7a5173f6 100644 --- a/front/salix/components/topbar/style.scss +++ b/front/salix/components/topbar/style.scss @@ -2,15 +2,8 @@ vn-topbar { display: flex; + align-items: center; color: $color-font-dark; box-sizing: border-box; background-color: $color-header; - align-items: center; - - & > header { - height: inherit; - width: inherit; - display: flex; - align-items: center; - } } diff --git a/front/salix/components/topbar/topbar.js b/front/salix/components/topbar/topbar.js index 583354ad1..423b033ce 100644 --- a/front/salix/components/topbar/topbar.js +++ b/front/salix/components/topbar/topbar.js @@ -1,7 +1 @@ -import ngModule from '../../module'; import './style.scss'; - -ngModule.component('vnTopbar', { - template: require('./topbar.html'), - transclude: true -}); diff --git a/front/salix/components/user-popover/style.scss b/front/salix/components/user-popover/style.scss index 4277b98f6..5d1745ca1 100644 --- a/front/salix/components/user-popover/style.scss +++ b/front/salix/components/user-popover/style.scss @@ -11,7 +11,7 @@ font-size: 60px; border-radius: 50%; color: $color-font-dark; - background: $color-secondary; + background: $color-marginal; padding: .1em; } & > div { diff --git a/front/salix/module.js b/front/salix/module.js index 58bdec105..2354e0dff 100644 --- a/front/salix/module.js +++ b/front/salix/module.js @@ -62,9 +62,10 @@ export function config($translatePartialLoaderProvider, $httpProvider, $compileP $translatePartialLoaderProvider.addPart(appName); $httpProvider.interceptors.push('vnInterceptor'); - // $compileProvider.debugInfoEnabled(false); - $compileProvider.commentDirectivesEnabled(false); - $compileProvider.cssClassDirectivesEnabled(false); + $compileProvider + .debugInfoEnabled(false) + .commentDirectivesEnabled(false) + .cssClassDirectivesEnabled(false); } ngModule.config(config); diff --git a/front/salix/routes.js b/front/salix/routes.js index 48a92795e..600907ff1 100644 --- a/front/salix/routes.js +++ b/front/salix/routes.js @@ -1,41 +1,23 @@ import ngModule from './module'; import getMainRoute from 'core/lib/get-main-route'; -function loader(moduleName) { - load.$inject = ['vnModuleLoader']; - function load(moduleLoader) { - return moduleLoader.load(moduleName); - } - return load; -} - config.$inject = ['$stateProvider', '$urlRouterProvider']; function config($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/'); - $stateProvider.state('home', { - url: '/', - template: '', - description: 'Home' - }); - $stateProvider.state('login', { - url: '/login?continue', - template: '', - description: 'Login' - }); - - function getParams(route) { - let params = ''; - let temporalParams = []; - - if (!route.params) - return params; - - Object.keys(route.params).forEach(key => { - temporalParams.push(`${key} = "${route.params[key]}"`); + $stateProvider + .state('login', { + url: '/login?continue', + description: 'Login', + views: { + login: {template: ''} + } + }) + .state('home', { + url: '/', + description: 'Home', + template: '' }); - return temporalParams.join(' '); - } for (let file in window.routes) { let routeFile = window.routes[file]; @@ -68,5 +50,26 @@ function config($stateProvider, $urlRouterProvider) { $stateProvider.state(route.state, configRoute); } } + + function getParams(route) { + let params = ''; + let temporalParams = []; + + if (!route.params) + return params; + + Object.keys(route.params).forEach(key => { + temporalParams.push(`${key} = "${route.params[key]}"`); + }); + return temporalParams.join(' '); + } + + function loader(moduleName) { + load.$inject = ['vnModuleLoader']; + function load(moduleLoader) { + return moduleLoader.load(moduleName); + } + return load; + } } ngModule.config(config); diff --git a/front/salix/styles/misc.scss b/front/salix/styles/misc.scss index 0ae30becd..1f2d79981 100644 --- a/front/salix/styles/misc.scss +++ b/front/salix/styles/misc.scss @@ -123,25 +123,14 @@ html [scrollable] { font-size: 0.7em } } -[compact], .compact { - margin-left: auto; - margin-right: auto; - max-width: $width-md; -} -vn-empty-rows { - display: block; - text-align: center; - padding: 1.5em; - box-sizing: border-box; -} /* XXX: Deprecated, use classes with text prefix */ [color-main] { color: $color-main; } -[color-secondary] { - color: $color-secondary; +[color-marginal] { + color: $color-marginal; } [uppercase], .uppercase { text-transform: uppercase; diff --git a/modules/agency/front/basic-data/index.html b/modules/agency/front/basic-data/index.html index b0f94ddc0..ec5cc3b20 100644 --- a/modules/agency/front/basic-data/index.html +++ b/modules/agency/front/basic-data/index.html @@ -84,14 +84,17 @@ - - + + diff --git a/modules/agency/front/card/index.html b/modules/agency/front/card/index.html index 1fd22809a..ae6a7f10a 100644 --- a/modules/agency/front/card/index.html +++ b/modules/agency/front/card/index.html @@ -1,5 +1,5 @@ - + - - -
        + + + diff --git a/modules/agency/front/card/index.js b/modules/agency/front/card/index.js index 7c53e9294..4e8ac7e8c 100644 --- a/modules/agency/front/card/index.js +++ b/modules/agency/front/card/index.js @@ -1,38 +1,21 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -class Controller { - constructor($http, $stateParams) { - this.$http = $http; - this.$stateParams = $stateParams; - } - - $onInit() { - this.getCard(); - } - - getCard() { +class Controller extends ModuleCard { + reload() { let filter = { include: { relation: 'agencyMode', scope: {fields: ['name']} } }; - let json = encodeURIComponent(JSON.stringify(filter)); - let query = `Zones/${this.$stateParams.id}?filter=${json}`; - this.$http.get(query).then(res => { - if (res.data) - this.zone = res.data; - }); - } - reload() { - this.getCard(); + this.$http.get(`Zones/${this.$params.id}`, {filter}) + .then(res => this.zone = res.data); } } -Controller.$inject = ['$http', '$stateParams']; - -ngModule.component('vnZoneCard', { +ngModule.vnComponent('vnZoneCard', { template: require('./index.html'), controller: Controller }); diff --git a/modules/agency/front/card/index.spec.js b/modules/agency/front/card/index.spec.js index 190b77d0d..cc53fe946 100644 --- a/modules/agency/front/card/index.spec.js +++ b/modules/agency/front/card/index.spec.js @@ -1,35 +1,26 @@ import './index.js'; describe('Agency Component vnZoneCard', () => { - let $scope; let controller; let $httpBackend; - let $stateParams; + let data = {id: 1, name: 'fooName'}; beforeEach(ngModule('agency')); - beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $stateParams) => { $httpBackend = _$httpBackend_; - $scope = $rootScope.$new(); - $stateParams = {id: 1}; - controller = $componentController('vnZoneCard', {$scope, $stateParams}); + + let $element = angular.element('
        '); + controller = $componentController('vnZoneCard', {$element}); + + $stateParams.id = data.id; + $httpBackend.whenRoute('GET', 'Zones/:id').respond(data); })); - describe('getCard()', () => { - it(`should make a query and define zone property`, () => { - let filter = { - include: { - relation: 'agencyMode', - scope: {fields: ['name']} - } - }; - let json = encodeURIComponent(JSON.stringify(filter)); - $httpBackend.expectGET(`Zones/1?filter=${json}`).respond({id: 1}); - controller.getCard(); - $httpBackend.flush(); + it('should request data and set it on the controller', () => { + controller.reload(); + $httpBackend.flush(); - expect(controller.zone).toEqual({id: 1}); - }); + expect(controller.zone).toEqual(data); }); }); - diff --git a/modules/agency/front/create/index.html b/modules/agency/front/create/index.html index 716d5e50c..332e8a9b8 100644 --- a/modules/agency/front/create/index.html +++ b/modules/agency/front/create/index.html @@ -5,79 +5,82 @@ form="form" save="post"> -
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        -
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        diff --git a/modules/agency/front/delivery-days/index.html b/modules/agency/front/delivery-days/index.html index 286721068..dca452c63 100644 --- a/modules/agency/front/delivery-days/index.html +++ b/modules/agency/front/delivery-days/index.html @@ -32,9 +32,12 @@ - - - + + - - -
        + +
        -
        + is-loading="!data.events"> + diff --git a/modules/agency/front/index/index.html b/modules/agency/front/index/index.html index 18229cd34..56a790b44 100644 --- a/modules/agency/front/index/index.html +++ b/modules/agency/front/index/index.html @@ -6,63 +6,56 @@ data="zones" auto-load="true"> -
        - - - + + + + + + + + Id + Name + Agency + Closing + Price + + + + + + {{::zone.id}} + {{::zone.name}} + {{::zone.agencyMode.name}} + {{::zone.hour | date: 'HH:mm'}} + {{::zone.price | currency: 'EUR':2}} + + + + + + + + + + + - - - - - - Id - Name - Agency - Closing - Price - - - - - - {{::zone.id}} - {{::zone.name}} - {{::zone.agencyMode.name}} - {{::zone.hour | date: 'HH:mm'}} - {{::zone.price | currency: 'EUR':2}} - - - - - - - - - - - - - -
        + diff --git a/modules/agency/front/location/index.html b/modules/agency/front/location/index.html index 6882ccc5b..a64735982 100644 --- a/modules/agency/front/location/index.html +++ b/modules/agency/front/location/index.html @@ -3,25 +3,26 @@ url="Zones/{{$ctrl.$params.id}}/getLeaves" filter="::$ctrl.filter"> + + + + +
        - - - - - - - - - + + + + +
        diff --git a/modules/agency/front/location/index.js b/modules/agency/front/location/index.js index aff9dbe77..9fcd055b3 100644 --- a/modules/agency/front/location/index.js +++ b/modules/agency/front/location/index.js @@ -3,6 +3,10 @@ import Component from 'core/lib/component'; import './style.scss'; class Controller extends Component { + $postLink() { + this.onSearch(); + } + onSearch(params) { this.$.model.applyFilter({}, params).then(() => { const data = this.$.model.data; @@ -12,9 +16,8 @@ class Controller extends Component { onFetch(item) { const params = item ? {parentId: item.id} : null; - return this.$.model.applyFilter({}, params).then(() => { - return this.$.model.data; - }); + return this.$.model.applyFilter({}, params) + .then(() => this.$.model.data); } onSort(a, b) { diff --git a/modules/agency/front/location/style.scss b/modules/agency/front/location/style.scss index d03701e42..4972a5d29 100644 --- a/modules/agency/front/location/style.scss +++ b/modules/agency/front/location/style.scss @@ -2,13 +2,13 @@ vn-treeview-child { .content > .vn-check:not(.indeterminate) { - color: $color-main; + color: $color-button; & > .btn { - border-color: $color-main; + border-color: $color-button; } } .content > .vn-check.checked { - color: $color-main; + color: $color-button; } } \ No newline at end of file diff --git a/modules/agency/front/main/index.html b/modules/agency/front/main/index.html index d695d74aa..230bf7f6d 100644 --- a/modules/agency/front/main/index.html +++ b/modules/agency/front/main/index.html @@ -1,14 +1,11 @@ - - - - -
        -
        - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/modules/agency/front/main/index.js b/modules/agency/front/main/index.js index 223b78caa..3e8890310 100644 --- a/modules/agency/front/main/index.js +++ b/modules/agency/front/main/index.js @@ -1,6 +1,9 @@ import ngModule from '../module'; -import './style.scss'; +import ModuleMain from 'salix/components/module-main'; -ngModule.component('vnZone', { +export default class Zone extends ModuleMain {} + +ngModule.vnComponent('vnZone', { + controller: Zone, template: require('./index.html') }); diff --git a/modules/agency/front/main/style.scss b/modules/agency/front/main/style.scss deleted file mode 100644 index 21e4fc40c..000000000 --- a/modules/agency/front/main/style.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import "effects"; - -vn-zone { - ul.menu { - list-style-type: none; - padding: 0; - padding-top: $spacing-md; - margin: 0; - font-size: inherit; - - & > li > a { - @extend %clickable; - display: block; - color: inherit; - padding: .6em 2em; - } - } -} \ No newline at end of file diff --git a/modules/agency/front/routes.json b/modules/agency/front/routes.json index 26d619172..f16875620 100644 --- a/modules/agency/front/routes.json +++ b/modules/agency/front/routes.json @@ -4,12 +4,18 @@ "icon" : "icon-delivery", "validations" : true, "dependencies": ["worker"], - "menu": [ - {"state": "zone.card.basicData", "icon": "settings"}, - {"state": "zone.card.location", "icon": "my_location"}, - {"state": "zone.card.warehouses", "icon": "home"}, - {"state": "zone.card.events", "icon": "today"} - ], + "menus": { + "main": [ + {"state": "zone.index", "icon": "icon-delivery"}, + {"state": "zone.deliveryDays", "icon": "today"} + ], + "card": [ + {"state": "zone.card.basicData", "icon": "settings"}, + {"state": "zone.card.location", "icon": "my_location"}, + {"state": "zone.card.warehouses", "icon": "home"}, + {"state": "zone.card.events", "icon": "today"} + ] + }, "routes": [ { "url": "/zone", diff --git a/modules/agency/front/search-panel/index.html b/modules/agency/front/search-panel/index.html index 1fd07cbf5..a97428192 100644 --- a/modules/agency/front/search-panel/index.html +++ b/modules/agency/front/search-panel/index.html @@ -22,8 +22,8 @@ label="Agency" ng-model="filter.agencyModeFk" url="AgencyModes/isActive" - show-field="name" - value-field="id"> + value-field="id" + show-field="name"> diff --git a/modules/claim/front/basic-data/index.html b/modules/claim/front/basic-data/index.html index cd8cade9f..8f31df9bd 100644 --- a/modules/claim/front/basic-data/index.html +++ b/modules/claim/front/basic-data/index.html @@ -5,7 +5,7 @@ url="Claims/{{$ctrl.$stateParams.id}}/updateClaim" save="post"> -
        + - - - - -
        - + + + + + diff --git a/modules/claim/front/card/index.js b/modules/claim/front/card/index.js index 7c0c348a9..0c77e1fd4 100644 --- a/modules/claim/front/card/index.js +++ b/modules/claim/front/card/index.js @@ -1,12 +1,12 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -class Controller { - constructor($http, $state) { - this.$http = $http; - this.$state = $state; - this.filter = { +class Controller extends ModuleCard { + reload() { + let filter = { include: [ - {relation: 'worker', + { + relation: 'worker', scope: { fields: ['userFk'], include: { @@ -16,8 +16,7 @@ class Controller { } } } - }, - { + }, { relation: 'ticket', scope: { fields: ['agencyModeFk'], @@ -25,14 +24,12 @@ class Controller { relation: 'agencyMode' } } - }, - { + }, { relation: 'claimState', scope: { fields: ['id', 'description'] } - }, - { + }, { relation: 'client', scope: { fields: ['salesPersonFk', 'name'], @@ -53,29 +50,13 @@ class Controller { } ] }; - } - $onInit() { - this.getCard(); - } - - getCard() { - let json = encodeURIComponent(JSON.stringify(this.filter)); - let query = `Claims/${this.$state.params.id}?filter=${json}`; - this.$http.get(query).then(res => { - if (res.data) - this.claim = res.data; - }); - } - - reload() { - this.getCard(); + this.$http.get(`Claims/${this.$params.id}`, {filter}) + .then(res => this.claim = res.data); } } -Controller.$inject = ['$http', '$state']; - -ngModule.component('vnClaimCard', { +ngModule.vnComponent('vnClaimCard', { template: require('./index.html'), controller: Controller }); diff --git a/modules/claim/front/card/index.spec.js b/modules/claim/front/card/index.spec.js index dfd106e89..1b2344925 100644 --- a/modules/claim/front/card/index.spec.js +++ b/modules/claim/front/card/index.spec.js @@ -2,29 +2,27 @@ import './index.js'; describe('Claim', () => { describe('Component vnClaimCard', () => { - let $scope; let controller; let $httpBackend; - let $state; + let data = {id: 1, name: 'fooName'}; beforeEach(ngModule('claim')); - beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $stateParams) => { $httpBackend = _$httpBackend_; - $scope = $rootScope.$new(); - $state = {params: {id: 1}}; - controller = $componentController('vnClaimCard', {$scope, $state}); + + let $element = angular.element('
        '); + controller = $componentController('vnClaimCard', {$element}); + + $stateParams.id = data.id; + $httpBackend.whenRoute('GET', 'Claims/:id').respond(data); })); - describe('getCard()', () => { - it(`should make a query and save the data in claim`, () => { - let json = encodeURIComponent(JSON.stringify(controller.filter)); - $httpBackend.expectGET(`Claims/${controller.$state.params.id}?filter=${json}`).respond({id: 1}); - controller.getCard(); - $httpBackend.flush(); + it('should request data and set it on the controller', () => { + controller.reload(); + $httpBackend.flush(); - expect(controller.claim).toEqual({id: 1}); - }); + expect(controller.claim).toEqual(data); }); }); }); diff --git a/modules/claim/front/development/index.html b/modules/claim/front/development/index.html index 281eb0188..cf777f31a 100644 --- a/modules/claim/front/development/index.html +++ b/modules/claim/front/development/index.html @@ -36,7 +36,7 @@ data="claimDevelopments" form="form"> - + diff --git a/modules/claim/front/index.js b/modules/claim/front/index.js index 53aa5e9da..4ea9ac6cc 100644 --- a/modules/claim/front/index.js +++ b/modules/claim/front/index.js @@ -1,5 +1,6 @@ export * from './module'; +import './main'; import './index/'; import './action'; import './basic-data'; diff --git a/modules/claim/front/index/index.html b/modules/claim/front/index/index.html index ca232b3dc..c85632571 100644 --- a/modules/claim/front/index/index.html +++ b/modules/claim/front/index/index.html @@ -6,67 +6,60 @@ order="claimStateFk ASC, created DESC" auto-load="true"> - + diff --git a/modules/claim/front/main/index.html b/modules/claim/front/main/index.html new file mode 100644 index 000000000..e733162b1 --- /dev/null +++ b/modules/claim/front/main/index.html @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/claim/front/main/index.js b/modules/claim/front/main/index.js new file mode 100644 index 000000000..77b051897 --- /dev/null +++ b/modules/claim/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Claim extends ModuleMain {} + +ngModule.vnComponent('vnClaim', { + controller: Claim, + template: require('./index.html') +}); diff --git a/modules/claim/front/routes.json b/modules/claim/front/routes.json index bda7da74b..80bc77c49 100644 --- a/modules/claim/front/routes.json +++ b/modules/claim/front/routes.json @@ -4,13 +4,18 @@ "icon": "icon-claims", "validations": true, "dependencies": ["worker", "item", "client"], - "menu": [ - {"state": "claim.card.basicData", "icon": "settings"}, - {"state": "claim.card.detail", "icon": "icon-details"}, - {"state": "claim.card.dms.index", "icon": "image"}, - {"state": "claim.card.development", "icon": "icon-traceability"}, - {"state": "claim.card.action", "icon": "icon-actions"} - ], + "menus": { + "main": [ + {"state": "claim.index", "icon": "icon-claims"} + ], + "card": [ + {"state": "claim.card.basicData", "icon": "settings"}, + {"state": "claim.card.detail", "icon": "icon-details"}, + {"state": "claim.card.dms.index", "icon": "image"}, + {"state": "claim.card.development", "icon": "icon-traceability"}, + {"state": "claim.card.action", "icon": "icon-actions"} + ] + }, "keybindings": [ {"key": "r", "state": "claim.index"} ], @@ -19,7 +24,7 @@ "url": "/claim", "state": "claim", "abstract": true, - "component": "ui-view", + "component": "vn-claim", "description": "Claims" }, { "url": "/index?q", diff --git a/modules/client/front/address/create/index.html b/modules/client/front/address/create/index.html index 3e9c4ab41..43f6e3589 100644 --- a/modules/client/front/address/create/index.html +++ b/modules/client/front/address/create/index.html @@ -14,7 +14,7 @@ data="observations" auto-load="true"> - + - + - + - - - - -
        - + + + + + diff --git a/modules/client/front/card/index.js b/modules/client/front/card/index.js index c785644d9..5aacc83ea 100644 --- a/modules/client/front/card/index.js +++ b/modules/client/front/card/index.js @@ -1,28 +1,12 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -export default class Controller { - constructor($scope, $stateParams, $http) { - this.$scope = $scope; - this.$http = $http; - this.$stateParams = $stateParams; - this.client = null; - } - - $onInit() { - this.getCard(); - } - - getCard() { - this.$http.get(`Clients/${this.$stateParams.id}/getCard`).then(response => { - this.client = response.data; - }); - } - +export default class Controller extends ModuleCard { reload() { - this.getCard(); + this.$http.get(`Clients/${this.$params.id}/getCard`) + .then(res => this.client = res.data); } } -Controller.$inject = ['$scope', '$stateParams', '$http']; ngModule.component('vnClientCard', { template: require('./index.html'), diff --git a/modules/client/front/card/index.spec.js b/modules/client/front/card/index.spec.js index 502e04677..72272fe89 100644 --- a/modules/client/front/card/index.spec.js +++ b/modules/client/front/card/index.spec.js @@ -2,21 +2,27 @@ import './index'; describe('Client', () => { describe('Component vnClientCard', () => { - let $componentController; - let $scope; let controller; + let $httpBackend; + let data = {id: 1, name: 'fooName'}; beforeEach(ngModule('client')); - beforeEach(angular.mock.inject((_$componentController_, $rootScope) => { - $componentController = _$componentController_; - $scope = $rootScope; - controller = $componentController('vnClientCard', {$scope: $scope}); + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $stateParams) => { + $httpBackend = _$httpBackend_; + + let $element = angular.element('
        '); + controller = $componentController('vnClientCard', {$element}); + + $stateParams.id = data.id; + $httpBackend.whenRoute('GET', 'Clients/:id/getCard').respond(data); })); - it('should define and set client property to null in the module instance', () => { - expect(controller.client).toBeDefined(); - expect(controller.client).toBe(null); + it('should request data and set it on the controller', () => { + controller.$onInit(); + $httpBackend.flush(); + + expect(controller.client).toEqual(data); }); }); }); diff --git a/modules/client/front/contact/index.html b/modules/client/front/contact/index.html index fa58f27d4..2cefdd86d 100644 --- a/modules/client/front/contact/index.html +++ b/modules/client/front/contact/index.html @@ -11,7 +11,7 @@ data="contacts" form="form"> - + -
        - - - - - - - {{firstName}} {{lastName}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        \ No newline at end of file +
        + + + + + + {{firstName}} {{lastName}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + \ No newline at end of file diff --git a/modules/client/front/credit-insurance/create/index.html b/modules/client/front/credit-insurance/create/index.html index 5dbe258b6..d1dc081b7 100644 --- a/modules/client/front/credit-insurance/create/index.html +++ b/modules/client/front/credit-insurance/create/index.html @@ -1,4 +1,4 @@ -
        + - + - + -
        +
        diff --git a/modules/client/front/dms/edit/index.html b/modules/client/front/dms/edit/index.html index a63a58c44..dbc2e0ed1 100644 --- a/modules/client/front/dms/edit/index.html +++ b/modules/client/front/dms/edit/index.html @@ -7,7 +7,7 @@ ng-submit="$ctrl.onSubmit()" class="vn-ma-md" enctype="multipart/form-data"> -
        +
        - + - + - + + + + + + + + \ No newline at end of file diff --git a/modules/client/front/main/index.js b/modules/client/front/main/index.js new file mode 100644 index 000000000..890165a19 --- /dev/null +++ b/modules/client/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Client extends ModuleMain {} + +ngModule.vnComponent('vnClient', { + controller: Client, + template: require('./index.html') +}); diff --git a/modules/client/front/note/create/index.html b/modules/client/front/note/create/index.html index 00a18edba..c9c351199 100644 --- a/modules/client/front/note/create/index.html +++ b/modules/client/front/note/create/index.html @@ -6,7 +6,7 @@ save="post" form="form"> - + - + - + - + - - - - -
        - + + + + + diff --git a/modules/invoiceOut/front/card/index.js b/modules/invoiceOut/front/card/index.js index c1a934924..0ad91f4c2 100644 --- a/modules/invoiceOut/front/card/index.js +++ b/modules/invoiceOut/front/card/index.js @@ -1,11 +1,9 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -export default class Controller { - constructor($stateParams, $http) { - this.$http = $http; - this.$stateParams = $stateParams; - this.route = null; - this.filter = { +class Controller extends ModuleCard { + reload() { + const filter = { fields: [ 'id', 'ref', @@ -28,24 +26,11 @@ export default class Controller { } ] }; - } - $onInit() { - this.getCard(); - } - - getCard() { - const params = {filter: this.filter}; - this.$http.get(`InvoiceOuts/${this.$stateParams.id}`, {params}).then(response => { - this.invoiceOut = response.data; - }); - } - - reload() { - this.getCard(); + this.$http.get(`InvoiceOuts/${this.$params.id}`, {filter}) + .then(res => this.invoiceOut = res.data); } } -Controller.$inject = ['$stateParams', '$http']; ngModule.component('vnInvoiceOutCard', { template: require('./index.html'), diff --git a/modules/invoiceOut/front/index.js b/modules/invoiceOut/front/index.js index 239bfd812..9843e188b 100644 --- a/modules/invoiceOut/front/index.js +++ b/modules/invoiceOut/front/index.js @@ -1,5 +1,6 @@ export * from './module'; +import './main'; import './index/'; import './search-panel'; import './summary'; diff --git a/modules/invoiceOut/front/index/index.html b/modules/invoiceOut/front/index/index.html index 1a74b28b4..c798b8bc6 100644 --- a/modules/invoiceOut/front/index/index.html +++ b/modules/invoiceOut/front/index/index.html @@ -5,72 +5,65 @@ data="invoiceOuts" order="issued DESC"> -
        + diff --git a/modules/invoiceOut/front/main/index.html b/modules/invoiceOut/front/main/index.html new file mode 100644 index 000000000..18e72ed5e --- /dev/null +++ b/modules/invoiceOut/front/main/index.html @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/invoiceOut/front/main/index.js b/modules/invoiceOut/front/main/index.js new file mode 100644 index 000000000..ad37e9c4b --- /dev/null +++ b/modules/invoiceOut/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class InvoiceOut extends ModuleMain {} + +ngModule.vnComponent('vnInvoiceOut', { + controller: InvoiceOut, + template: require('./index.html') +}); diff --git a/modules/invoiceOut/front/routes.json b/modules/invoiceOut/front/routes.json index eb278ebd8..8f828a634 100644 --- a/modules/invoiceOut/front/routes.json +++ b/modules/invoiceOut/front/routes.json @@ -4,12 +4,17 @@ "icon": "icon-invoices", "validations" : true, "dependencies": ["worker", "client", "ticket"], + "menus": { + "main": [ + {"state": "invoiceOut.index", "icon": "icon-invoices"} + ] + }, "routes": [ { "url": "/invoice-out", "state": "invoiceOut", "abstract": true, - "component": "ui-view", + "component": "vn-invoice-out", "description": "InvoiceOut", "acl": ["employee"] }, diff --git a/modules/item/front/barcode/index.html b/modules/item/front/barcode/index.html index 316fff80f..dba745d28 100644 --- a/modules/item/front/barcode/index.html +++ b/modules/item/front/barcode/index.html @@ -11,7 +11,7 @@ data="barcodes" form="form"> - + - + - + - - - - -
        - + + + + + diff --git a/modules/item/front/card/index.js b/modules/item/front/card/index.js index c5adb14b8..12167500f 100644 --- a/modules/item/front/card/index.js +++ b/modules/item/front/card/index.js @@ -1,29 +1,13 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -class Controller { - constructor($http, $stateParams) { - this.$http = $http; - this.$stateParams = $stateParams; - this.item = null; - } - - $onInit() { - this.getCard(); - } - - getCard() { - this.$http.get(`Items/${this.$stateParams.id}/getCard`).then(response => { - this.item = response.data; - }); - } - +class Controller extends ModuleCard { reload() { - this.getCard(); + this.$http.get(`Items/${this.$params.id}/getCard`) + .then(res => this.item = res.data); } } -Controller.$inject = ['$http', '$stateParams']; - ngModule.component('vnItemCard', { template: require('./index.html'), controller: Controller diff --git a/modules/item/front/card/index.spec.js b/modules/item/front/card/index.spec.js index 1db1db140..c0ea80e69 100644 --- a/modules/item/front/card/index.spec.js +++ b/modules/item/front/card/index.spec.js @@ -2,30 +2,27 @@ import './index.js'; describe('Item', () => { describe('Component vnItemCard', () => { - let $httpBackend; - let $stateParams; let controller; + let $httpBackend; + let data = {id: 1, name: 'fooName'}; beforeEach(ngModule('item')); - beforeEach(angular.mock.inject(($componentController, _$stateParams_, _$httpBackend_) => { + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $stateParams) => { $httpBackend = _$httpBackend_; - $stateParams = { - id: 123 - }; - controller = $componentController('vnItemCard', {$stateParams}); + + let $element = angular.element('
        '); + controller = $componentController('vnItemCard', {$element}); + + $stateParams.id = data.id; + $httpBackend.whenRoute('GET', 'Items/:id/getCard').respond(data); })); - describe('getCard()', () => { - it('should request to set the item into the controller', () => { - let response = {id: 123}; - $httpBackend.when('GET', `Items/123/getCard`).respond(response); - $httpBackend.expect('GET', `Items/123/getCard`); - controller.getCard(); - $httpBackend.flush(); + it('should request data and set it on the controller', () => { + controller.reload(); + $httpBackend.flush(); - expect(controller.item).toEqual(response); - }); + expect(controller.item).toEqual(data); }); }); }); diff --git a/modules/item/front/create/index.html b/modules/item/front/create/index.html index 8d22d7145..0c00aa8e9 100644 --- a/modules/item/front/create/index.html +++ b/modules/item/front/create/index.html @@ -5,61 +5,59 @@ form="form" save="post"> -
        - - - - - - - - - -
        {{::code}}
        -
        {{::name}}
        -
        -
        - - -
        {{::id}}
        -
        {{::description}}
        -
        -
        -
        - - - - -
        - - - - - - - -
        +
        + + + + + + + + +
        {{::code}}
        +
        {{::name}}
        +
        +
        + + +
        {{::id}}
        +
        {{::description}}
        +
        +
        +
        + + + + +
        + + + + + + +
        diff --git a/modules/item/front/diary/index.html b/modules/item/front/diary/index.html index f6ecf7bfd..fbe134164 100644 --- a/modules/item/front/diary/index.html +++ b/modules/item/front/diary/index.html @@ -6,7 +6,7 @@ auto-load="false"> - + - + show-fields="$ctrl.showFields" + vn-uvc="itemIndex"> + + + + Id + Grouping + Packing + Description + Stems + Size + Niche + Type + Category + Intrastat + Origin + Buyer + Density + Active + + + + + + + + + + + {{::item.id | zeroFill:6}} + + + {{::item.grouping | dashIfEmpty}} + {{::item.packing | dashIfEmpty}} + + + + + {{::item.stems}} + {{::item.size}} + {{::item.niche}} + + {{::item.type}} + + + {{::item.category}} + + + {{::item.intrastat}} + + {{::item.origin}} + + + {{::item.userNickname}} + + + {{::item.density}} + + + + + + + + + + + + + + + + + diff --git a/modules/item/front/index/index.js b/modules/item/front/index/index.js index 93a83c6be..087021577 100644 --- a/modules/item/front/index/index.js +++ b/modules/item/front/index/index.js @@ -14,22 +14,6 @@ class Controller { id: false, actions: false }; - this.moreOptions = [ - {callback: this.goToTicketRequest, name: 'Buy requests', acl: 'buyer'} - ]; - } - - onMoreOpen() { - let options = this.moreOptions.filter(o => this.aclService.hasAny([o.acl])); - this.$.moreButton.data = options; - } - - onMoreChange(callback) { - callback.call(this); - } - - goToTicketRequest() { - this.$state.go('item.request'); } stopEvent(event) { diff --git a/modules/item/front/main/index.html b/modules/item/front/main/index.html new file mode 100644 index 000000000..758bfd55e --- /dev/null +++ b/modules/item/front/main/index.html @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/item/front/main/index.js b/modules/item/front/main/index.js new file mode 100644 index 000000000..f34369982 --- /dev/null +++ b/modules/item/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Items extends ModuleMain {} + +ngModule.vnComponent('vnItems', { + controller: Items, + template: require('./index.html') +}); diff --git a/modules/item/front/niche/index.html b/modules/item/front/niche/index.html index b361ed1e2..70dabe671 100644 --- a/modules/item/front/niche/index.html +++ b/modules/item/front/niche/index.html @@ -11,7 +11,7 @@ data="niches" form="form"> -
        + - -
        - - - - - - - - - - Ticket ID - Shipped - Warehouse - SalesPerson - Description - Requested - Price - Atender - Item - Achieved - Concept - State - - - - - - - {{request.ticketFk}} - - - - - {{::request.shipped | date: 'dd/MM/yyyy'}} - - - {{::request.warehouse}} - - - {{::request.salesPersonNickname}} - - - {{::request.description}} - {{::request.quantity}} - {{::request.price | currency: 'EUR':2}} - - - {{::request.atenderNickname}} - - - - {{request.itemFk}} - - - - - - - {{request.saleQuantity}} - - - - - - - - {{request.itemDescription}} - - - {{$ctrl.getState(request.isOk)}} - - - - - - - - - - - -
        - + + + + + + + + + + Ticket ID + Shipped + Warehouse + SalesPerson + Description + Requested + Price + Atender + Item + Achieved + Concept + State + + + + + + + {{request.ticketFk}} + + + + + {{::request.shipped | date: 'dd/MM/yyyy'}} + + + {{::request.warehouse}} + + + {{::request.salesPersonNickname}} + + + {{::request.description}} + {{::request.quantity}} + {{::request.price | currency: 'EUR':2}} + + + {{::request.atenderNickname}} + + + + {{request.itemFk}} + + + + + + + {{request.saleQuantity}} + + + + + + + + {{request.itemDescription}} + + + {{$ctrl.getState(request.isOk)}} + + + + + + + + + + + diff --git a/modules/item/front/routes.json b/modules/item/front/routes.json index e50a7f112..bda4f18a9 100644 --- a/modules/item/front/routes.json +++ b/modules/item/front/routes.json @@ -4,17 +4,23 @@ "icon": "icon-item", "validations" : true, "dependencies": ["worker", "client", "ticket"], - "menu": [ - {"state": "item.card.basicData", "icon": "settings"}, - {"state": "item.card.tags", "icon": "icon-tags"}, - {"state": "item.card.tax", "icon": "icon-tax"}, - {"state": "item.card.niche", "icon": "place"}, - {"state": "item.card.botanical", "icon": "local_florist"}, - {"state": "item.card.itemBarcode", "icon": "icon-barcode"}, - {"state": "item.card.diary", "icon": "icon-transaction"}, - {"state": "item.card.last-entries", "icon": "icon-regentry"}, - {"state": "item.card.log", "icon": "history"} - ], + "menus": { + "main": [ + {"state": "item.index", "icon": "icon-item"}, + {"state": "item.request", "icon": "pan_tool"} + ], + "card": [ + {"state": "item.card.basicData", "icon": "settings"}, + {"state": "item.card.tags", "icon": "icon-tags"}, + {"state": "item.card.tax", "icon": "icon-tax"}, + {"state": "item.card.niche", "icon": "place"}, + {"state": "item.card.botanical", "icon": "local_florist"}, + {"state": "item.card.itemBarcode", "icon": "icon-barcode"}, + {"state": "item.card.diary", "icon": "icon-transaction"}, + {"state": "item.card.last-entries", "icon": "icon-regentry"}, + {"state": "item.card.log", "icon": "history"} + ] + }, "keybindings": [ {"key": "a", "state": "item.index"} ], @@ -24,7 +30,7 @@ "state": "item", "abstract": true, "description": "Items", - "component": "ui-view" + "component": "vn-items" }, { "url": "/index?q", "state": "item.index", diff --git a/modules/item/front/tags/index.html b/modules/item/front/tags/index.html index 7958f9e1e..b7b61107d 100644 --- a/modules/item/front/tags/index.html +++ b/modules/item/front/tags/index.html @@ -19,7 +19,7 @@ data="tags" auto-load="true"> -
        + - + - + - - - - -
        - + + + + + diff --git a/modules/order/front/card/index.js b/modules/order/front/card/index.js index 9524a8ec4..e79167761 100644 --- a/modules/order/front/card/index.js +++ b/modules/order/front/card/index.js @@ -1,31 +1,35 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -class Controller { - constructor($http, $state) { - this.$http = $http; - this.$state = $state; - this.order = {}; - this.filter = { +class Controller extends ModuleCard { + reload() { + let filter = { include: [ { - relation: 'agencyMode', scope: { + relation: 'agencyMode', + scope: { fields: ['name'] } - }, - { - relation: 'address', scope: { + }, { + relation: 'address', + scope: { fields: ['nickname'] } - }, - { - relation: 'rows', scope: { + }, { + relation: 'rows', + scope: { fields: ['id'] } - }, - { + }, { relation: 'client', scope: { - fields: ['salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked'], + fields: [ + 'salesPersonFk', + 'name', + 'isActive', + 'isFreezed', + 'isTaxDataChecked' + ], include: { relation: 'salesPerson', scope: { @@ -42,40 +46,18 @@ class Controller { } ] }; - } - $onInit() { - this.getCard(); - } - - getCard() { - let json = encodeURIComponent(JSON.stringify(this.filter)); - let query = `Orders/${this.$state.params.id}?filter=${json}`; - this.$http.get(query).then(res => { - if (res.data && res.data.rows) { - if (res.data.rows.length == 0) - delete res.data.rows; - this.order = res.data; - this.getTotal(); - } - }); - } - - reload() { - this.getCard(); - } - - getTotal() { - let query = `Orders/${this.$state.params.id}/getTotal`; - this.$http.get(query).then(res => { - if (res.data) - this.order.total = res.data; + this.$q.all([ + this.$http.get(`Orders/${this.$params.id}`, {filter}) + .then(res => this.order = res.data), + this.$http.get(`Orders/${this.$params.id}/getTotal`) + .then(res => ({total: res.data})) + ]).then(res => { + this.order = Object.assign.apply(null, res); }); } } -Controller.$inject = ['$http', '$state']; - ngModule.component('vnOrderCard', { template: require('./index.html'), controller: Controller diff --git a/modules/order/front/card/index.spec.js b/modules/order/front/card/index.spec.js index a962ba5ec..19d070920 100644 --- a/modules/order/front/card/index.spec.js +++ b/modules/order/front/card/index.spec.js @@ -2,61 +2,29 @@ import './index.js'; describe('Order', () => { describe('Component vnOrderCard', () => { - let $scope; let controller; let $httpBackend; - let $state; + let data = {id: 1, name: 'fooName'}; + let total = 10.5; beforeEach(ngModule('order')); - beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => { + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $stateParams) => { $httpBackend = _$httpBackend_; - $scope = $rootScope.$new(); - $scope.card = {createOrder: () => {}}; - $state = {params: {id: 1}}; - controller = $componentController('vnOrderCard', {$scope, $state}); + + let $element = angular.element('
        '); + controller = $componentController('vnOrderCard', {$element}); + + $stateParams.id = data.id; + $httpBackend.whenRoute('GET', 'Orders/:id').respond(data); + $httpBackend.whenRoute('GET', 'Orders/:id/getTotal').respond(200, total); })); - describe('getCard()', () => { - it(`should make a query, save the data in order and call get order if the response has data`, () => { - spyOn(controller, 'getTotal'); - let json = encodeURIComponent(JSON.stringify(controller.filter)); - $httpBackend.expectGET(`Orders/${controller.$state.params.id}?filter=${json}`).respond({rows: [1, 2, 3]}); - controller.getCard(); - $httpBackend.flush(); + it('should request data and total, merge them, and set it on the controller', () => { + controller.reload(); + $httpBackend.flush(); - expect(controller.order).toEqual({rows: [1, 2, 3]}); - expect(controller.getTotal).toHaveBeenCalledWith(); - }); - - it(`should make a query and not call getTotal if the response is not defined`, () => { - spyOn(controller, 'getTotal'); - let json = encodeURIComponent(JSON.stringify(controller.filter)); - $httpBackend.expectGET(`Orders/${controller.$state.params.id}?filter=${json}`).respond(undefined); - controller.getCard(); - $httpBackend.flush(); - - expect(controller.order).toEqual({}); - expect(controller.getTotal).not.toHaveBeenCalledWith(); - }); - }); - - describe('getTotal()', () => { - it(`should make a query and save the data in order.total`, () => { - $httpBackend.expectGET(`Orders/${controller.$state.params.id}/getTotal`).respond('20M'); - controller.getTotal(); - $httpBackend.flush(); - - expect(controller.order.total).toEqual('20M'); - }); - - it(`should make a query and not save the respones if is not defined`, () => { - $httpBackend.expectGET(`Orders/${controller.$state.params.id}/getTotal`).respond(); - controller.getTotal(); - $httpBackend.flush(); - - expect(controller.order.total).toEqual(undefined); - }); + expect(controller.order).toEqual(Object.assign({}, data, {total})); }); }); }); diff --git a/modules/order/front/catalog/index.html b/modules/order/front/catalog/index.html index 37ef1fd90..8002c2b10 100644 --- a/modules/order/front/catalog/index.html +++ b/modules/order/front/catalog/index.html @@ -7,8 +7,7 @@ on-data-change="$ctrl.onDataChange()"> + model="model">
        diff --git a/modules/order/front/create/index.html b/modules/order/front/create/index.html index d557bd21a..11de7ff6c 100644 --- a/modules/order/front/create/index.html +++ b/modules/order/front/create/index.html @@ -1,11 +1,9 @@ -
        -
        - - - - - - - -
        +
        + + + + + + +
        \ No newline at end of file diff --git a/modules/order/front/descriptor/index.js b/modules/order/front/descriptor/index.js index ec65d3b4c..0d8a1e14a 100644 --- a/modules/order/front/descriptor/index.js +++ b/modules/order/front/descriptor/index.js @@ -14,6 +14,7 @@ class Controller { set order(value) { this._order = value; + if (!value) return; if (value.isConfirmed) { this._quicklinks = { diff --git a/modules/order/front/index.js b/modules/order/front/index.js index 2232a7501..0d8d0d686 100644 --- a/modules/order/front/index.js +++ b/modules/order/front/index.js @@ -1,5 +1,6 @@ export * from './module'; +import './main'; import './index/'; import './card'; import './descriptor'; diff --git a/modules/order/front/index/index.html b/modules/order/front/index/index.html index a6ec84392..20dd4a231 100644 --- a/modules/order/front/index/index.html +++ b/modules/order/front/index/index.html @@ -5,74 +5,71 @@ data="orders" order="landed DESC, clientFk"> -
        - - - + + + + + + + + Id + Client + Sales person + Confirmed + Created from + Created + Landed + Company + Total + + + + + {{::order.id}} + + + {{::order.clientName}} + + + + + {{::order.workerNickname | dashIfEmpty}} + + + + + + + {{::order.sourceApp}} + {{::order.created | date: 'dd/MM/yyyy HH:mm'}} + {{::order.landed | date:'dd/MM/yyyy'}} + {{::order.companyCode}} + {{::order.total | currency: 'EUR': 2 | dashIfEmpty}} + + + + + + + - - - - - - Id - Client - Sales person - Confirmed - Created from - Created - Landed - Company - Total - - - - - {{::order.id}} - - - {{::order.clientName}} - - - - - {{::order.workerNickname | dashIfEmpty}} - - - - - - - {{::order.sourceApp}} - {{::order.created | date: 'dd/MM/yyyy HH:mm'}} - {{::order.landed | date:'dd/MM/yyyy'}} - {{::order.companyCode}} - {{::order.total | currency: 'EUR': 2 | dashIfEmpty}} - - - - - - - - - -
        - + + + + + + + + + \ No newline at end of file diff --git a/modules/order/front/main/index.js b/modules/order/front/main/index.js new file mode 100644 index 000000000..7513d2144 --- /dev/null +++ b/modules/order/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Order extends ModuleMain {} + +ngModule.vnComponent('vnOrder', { + controller: Order, + template: require('./index.html') +}); diff --git a/modules/order/front/routes.json b/modules/order/front/routes.json index 0f610169d..86eda488f 100644 --- a/modules/order/front/routes.json +++ b/modules/order/front/routes.json @@ -4,18 +4,23 @@ "icon": "icon-basket", "validations": true, "dependencies": ["worker", "item", "ticket"], - "menu": [ - {"state": "order.card.basicData", "icon": "settings"}, - {"state": "order.card.catalog", "icon": "icon-basket"}, - {"state": "order.card.volume", "icon": "icon-volume"}, - {"state": "order.card.line", "icon": "icon-lines"} - ], + "menus": { + "main": [ + {"state": "order.index", "icon": "icon-basket"} + ], + "card": [ + {"state": "order.card.basicData", "icon": "settings"}, + {"state": "order.card.catalog", "icon": "icon-basket"}, + {"state": "order.card.volume", "icon": "icon-volume"}, + {"state": "order.card.line", "icon": "icon-lines"} + ] + }, "routes": [ { "url": "/order", "state": "order", "abstract": true, - "component": "ui-view", + "component": "vn-order", "description": "Orders" }, { "url": "/index?q", diff --git a/modules/route/front/basic-data/index.html b/modules/route/front/basic-data/index.html index b63970bcc..dcdfd37d7 100644 --- a/modules/route/front/basic-data/index.html +++ b/modules/route/front/basic-data/index.html @@ -5,7 +5,7 @@ form="form" save="patch"> - + - - - - -
        - + + + + + diff --git a/modules/route/front/card/index.js b/modules/route/front/card/index.js index 2e3acb9c1..e2d8f9b16 100644 --- a/modules/route/front/card/index.js +++ b/modules/route/front/card/index.js @@ -1,11 +1,9 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -export default class Controller { - constructor($stateParams, $http) { - this.$http = $http; - this.$stateParams = $stateParams; - this.route = null; - this.filter = { +class Controller extends ModuleCard { + reload() { + let filter = { fields: [ 'id', 'workerFk', @@ -22,22 +20,18 @@ export default class Controller { 'cost', 'zoneFk' ], - - where: {id: $stateParams.id}, include: [ { relation: 'agencyMode', scope: { fields: ['id', 'name'] } - }, - { + }, { relation: 'vehicle', scope: { fields: ['id', 'm3'] } - }, - { + }, { relation: 'zone', scope: { fields: ['id', 'name'] @@ -45,24 +39,11 @@ export default class Controller { } ] }; - } - $onInit() { - this.getCard(); - } - - getCard() { - let json = encodeURIComponent(JSON.stringify(this.filter)); - this.$http.get(`Routes?filter=${json}`).then(response => { - this.route = response.data[0]; - }); - } - - reload() { - this.getCard(); + this.$http.get(`Routes/${this.$params.id}`, {filter}) + .then(res => this.route = res.data); } } -Controller.$inject = ['$stateParams', '$http']; ngModule.component('vnRouteCard', { template: require('./index.html'), diff --git a/modules/route/front/create/index.html b/modules/route/front/create/index.html index 97747fca5..7f6a1f600 100644 --- a/modules/route/front/create/index.html +++ b/modules/route/front/create/index.html @@ -5,56 +5,54 @@ form="form" save="post"> -
        - - - - - - - - - - - - - - - - - - - - - - - - -
        +
        + + + + + + + + + + + + + + + + + + + + + + +
        diff --git a/modules/route/front/descriptor/index.js b/modules/route/front/descriptor/index.js index 438a2dda9..475cd9d51 100644 --- a/modules/route/front/descriptor/index.js +++ b/modules/route/front/descriptor/index.js @@ -56,7 +56,7 @@ class Controller { let url = `Routes/${this.route.id}/updateVolume`; this.$http.post(url).then(() => { this.vnApp.showSuccess(this.$translate.instant('Volume updated')); - this.card.reload(); + if (this.card) this.card.reload(); }); } } @@ -71,7 +71,7 @@ ngModule.component('vnRouteDescriptor', { quicklinks: '<' }, require: { - card: '^vnRouteCard' + card: '^?vnRouteCard' }, controller: Controller }); diff --git a/modules/route/front/index.js b/modules/route/front/index.js index a6530c6b8..ce8e80e95 100644 --- a/modules/route/front/index.js +++ b/modules/route/front/index.js @@ -1,5 +1,6 @@ export * from './module'; +import './main'; import './index/'; import './search-panel'; import './descriptor'; diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html index 9852eb880..c01112928 100644 --- a/modules/route/front/index/index.html +++ b/modules/route/front/index/index.html @@ -6,63 +6,55 @@ order="created DESC" auto-load="true"> - + diff --git a/modules/route/front/index/index.js b/modules/route/front/index/index.js index 823ef8bf4..8fdde810c 100644 --- a/modules/route/front/index/index.js +++ b/modules/route/front/index/index.js @@ -1,30 +1,15 @@ import ngModule from '../module'; export default class Controller { - constructor($scope, vnToken, vnConfig) { - this.accessToken = vnToken.token; + constructor($scope, vnToken) { this.$ = $scope; - this.vnConfig = vnConfig; - - this.setDefaultFilter(); - } - - setDefaultFilter() { - let to = new Date(); - to.setDate(to.getDate() + 1); - to.setHours(0, 0, 0, 0); - - let from = new Date(); - from.setHours(0, 0, 0, 0); - - this.filter = {from, to, warehouseFk: this.vnConfig.warehouseFk}; + this.accessToken = vnToken.token; } showWorkerDescriptor(event, workerFk) { if (event.defaultPrevented) return; - event.preventDefault(); - event.stopImmediatePropagation(); + event.stopPropagation(); this.selectedWorker = workerFk; this.$.workerDescriptor.parent = event.target; @@ -32,10 +17,12 @@ export default class Controller { } preview(event, route) { + if (event.defaultPrevented) return; + event.preventDefault(); + event.stopPropagation(); + this.routeSelected = route; this.$.summary.show(); - event.preventDefault(); - event.stopImmediatePropagation(); } onSearch(params) { @@ -45,8 +32,7 @@ export default class Controller { this.$.model.clear(); } } - -Controller.$inject = ['$scope', 'vnToken', 'vnConfig']; +Controller.$inject = ['$scope', 'vnToken']; ngModule.component('vnRouteIndex', { template: require('./index.html'), diff --git a/modules/route/front/index/style.scss b/modules/route/front/index/style.scss deleted file mode 100644 index d8c24a482..000000000 --- a/modules/route/front/index/style.scss +++ /dev/null @@ -1,5 +0,0 @@ -@import "./variables"; - -vn-route-index .index { - max-width: $width-lg; -} \ No newline at end of file diff --git a/modules/route/front/main/index.html b/modules/route/front/main/index.html new file mode 100644 index 000000000..f6e097b24 --- /dev/null +++ b/modules/route/front/main/index.html @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/route/front/main/index.js b/modules/route/front/main/index.js new file mode 100644 index 000000000..618989748 --- /dev/null +++ b/modules/route/front/main/index.js @@ -0,0 +1,26 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Route extends ModuleMain { + constructor($element, $, vnConfig) { + super($element, $); + this.vnConfig = vnConfig; + } + + $postLink() { + let to = new Date(); + to.setDate(to.getDate() + 1); + to.setHours(0, 0, 0, 0); + + let from = new Date(); + from.setHours(0, 0, 0, 0); + + this.filter = {from, to, warehouseFk: this.vnConfig.warehouseFk}; + } +} +Route.$inject = ['$element', '$scope', 'vnConfig']; + +ngModule.vnComponent('vnRoute', { + controller: Route, + template: require('./index.html') +}); diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index baffe9082..beb444abc 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -4,16 +4,22 @@ "icon": "icon-delivery", "validations" : true, "dependencies": ["client", "worker", "ticket"], - "menu": [ - {"state": "route.card.basicData", "icon": "settings"}, - {"state": "route.card.tickets", "icon": "icon-ticket"}, - {"state": "route.card.log", "icon": "history"}], + "menus": { + "main": [ + {"state": "route.index", "icon": "icon-delivery"} + ], + "card": [ + {"state": "route.card.basicData", "icon": "settings"}, + {"state": "route.card.tickets", "icon": "icon-ticket"}, + {"state": "route.card.log", "icon": "history"} + ] + }, "routes": [ { "url": "/route", "state": "route", "abstract": true, - "component": "ui-view", + "component": "vn-route", "description": "Routes", "acl": ["employee"] }, { diff --git a/modules/ticket/front/basic-data/index.html b/modules/ticket/front/basic-data/index.html index 4439069e8..f492283b0 100644 --- a/modules/ticket/front/basic-data/index.html +++ b/modules/ticket/front/basic-data/index.html @@ -1,14 +1,14 @@ - - - - -
        +
        + + + +
        \ No newline at end of file diff --git a/modules/ticket/front/card/index.html b/modules/ticket/front/card/index.html index c55064ce6..a7c70c484 100644 --- a/modules/ticket/front/card/index.html +++ b/modules/ticket/front/card/index.html @@ -1,7 +1,5 @@ - - - - - -
        -
        + + + + + diff --git a/modules/ticket/front/card/index.js b/modules/ticket/front/card/index.js index b05472bcb..fab63157e 100644 --- a/modules/ticket/front/card/index.js +++ b/modules/ticket/front/card/index.js @@ -1,18 +1,23 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -class Controller { - constructor($http, $state) { - this.$http = $http; - this.$state = $state; - this.filter = { +class Controller extends ModuleCard { + reload() { + let filter = { include: [ - {relation: 'warehouse', scope: {fields: ['name']}}, - {relation: 'invoiceOut', scope: {fields: ['id']}}, {relation: 'address'}, {relation: 'ship'}, - {relation: 'agencyMode', scope: {fields: ['name']}}, {relation: 'stowaway'}, { + relation: 'warehouse', + scope: {fields: ['name']} + }, { + relation: 'invoiceOut', + scope: {fields: ['id']} + }, { + relation: 'agencyMode', + scope: {fields: ['name']} + }, { relation: 'client', scope: { fields: ['salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked', 'credit'], @@ -29,8 +34,7 @@ class Controller { } }, }, - }, - { + }, { relation: 'state', scope: { fields: ['stateFk'], @@ -42,37 +46,18 @@ class Controller { }, ], }; + + this.$http.get(`Tickets/${this.$params.id}`, {filter}) + .then(res => this.onData(res.data)); } - $onInit() { - this.getCard(); - } - - getCard() { - const json = encodeURIComponent(JSON.stringify(this.filter)); - const query = `Tickets/${this.$state.params.id}?filter=${json}`; - this.$http.get(query).then(res => { - if (res.data) { - this.ticket = res.data; - this.getDebt(res.data.client.id); - } - }); - } - - getDebt(id) { - const query = `Clients/${id}/getDebt`; - this.$http.get(query).then(res => { - if (res.data) - this.ticket.client.debt = res.data.debt; - }); - } - reload() { - this.getCard(); + onData(data) { + this.ticket = data; + this.$http.get(`Clients/${data.client.id}/getDebt`) + .then(res => this.ticket.client.debt = res.data.debt); } } -Controller.$inject = ['$http', '$state']; - ngModule.component('vnTicketCard', { template: require('./index.html'), controller: Controller diff --git a/modules/ticket/front/card/index.spec.js b/modules/ticket/front/card/index.spec.js index 9df76aaff..33757860c 100644 --- a/modules/ticket/front/card/index.spec.js +++ b/modules/ticket/front/card/index.spec.js @@ -3,34 +3,31 @@ import './index'; describe('Ticket', () => { describe('Component vnTicketCard', () => { let controller; - let $state; let $httpBackend; + let data = { + id: 1, + client: {name: 'fooName'} + }; + let client = {debt: 10.5}; beforeEach(ngModule('ticket')); - beforeEach(angular.mock.inject(($componentController, _$state_, _$httpBackend_) => { - $state = _$state_; - $state.params.id = 1; + beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $stateParams) => { $httpBackend = _$httpBackend_; - controller = $componentController('vnTicketCard', {$state}); + + let $element = angular.element('
        '); + controller = $componentController('vnTicketCard', {$element}); + + $stateParams.id = data.id; + $httpBackend.whenRoute('GET', 'Tickets/:id').respond(data); + $httpBackend.whenRoute('GET', 'Clients/:id/getDebt').respond(client); })); - describe('getCard()', () => { - it('should perform a GET query and define the ticket property on controller', () => { - let filter = controller.filter; + it('should request data and set it on the controller', () => { + controller.reload(); + $httpBackend.flush(); - filter = encodeURIComponent(JSON.stringify(filter)); - - $httpBackend.when('GET', `Tickets/1?filter=${filter}`).respond({id: 1, client: {id: 1}}); - $httpBackend.expect('GET', `Tickets/1?filter=${filter}`); - $httpBackend.when('GET', `Clients/1/getDebt`).respond(); - $httpBackend.expect('GET', `Clients/1/getDebt`); - controller.getCard(); - $httpBackend.flush(); - - expect(controller.ticket).toBeDefined(); - expect(controller.ticket.id).toEqual(1); - }); + expect(controller.ticket).toMatchObject(data); }); }); }); diff --git a/modules/ticket/front/create/index.html b/modules/ticket/front/create/index.html index 97980d08a..3ec562752 100644 --- a/modules/ticket/front/create/index.html +++ b/modules/ticket/front/create/index.html @@ -1,11 +1,9 @@ -
        -
        - - - - - - - -
        +
        + + + + + + +
        \ No newline at end of file diff --git a/modules/ticket/front/dms/create/index.html b/modules/ticket/front/dms/create/index.html index 8c0b934b5..8e6af2b87 100644 --- a/modules/ticket/front/dms/create/index.html +++ b/modules/ticket/front/dms/create/index.html @@ -7,7 +7,7 @@ ng-submit="$ctrl.onSubmit()" class="vn-ma-md" enctype="multipart/form-data"> -
        +
        diff --git a/modules/ticket/front/dms/edit/index.html b/modules/ticket/front/dms/edit/index.html index a5e485dce..cf9af46d0 100644 --- a/modules/ticket/front/dms/edit/index.html +++ b/modules/ticket/front/dms/edit/index.html @@ -7,7 +7,7 @@ ng-submit="$ctrl.onSubmit()" class="vn-ma-md" enctype="multipart/form-data"> -
        +
        diff --git a/modules/ticket/front/index.js b/modules/ticket/front/index.js index b75398d9d..9f8e828c0 100644 --- a/modules/ticket/front/index.js +++ b/modules/ticket/front/index.js @@ -1,5 +1,6 @@ export * from './module'; +import './main'; import './index/'; import './search-panel'; import './card'; diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 1680d94d5..b303c3ae7 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -6,146 +6,142 @@ data="tickets" order="shipped DESC, zoneHour ASC, zoneMinute ASC, clientFk"> - - + + diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js index 2a2f3a238..9cf1c5483 100644 --- a/modules/ticket/front/index/index.js +++ b/modules/ticket/front/index/index.js @@ -10,13 +10,14 @@ export default class Controller { this.$state = $state; this.selectedTicket = null; this.moreOptions = [ - {callback: () => { - this.$state.go('ticket.weekly.index'); - }, name: 'Weekly tickets', always: true}, - {callback: () => { - this.setBalanceCreateDialog(); - this.$.balanceCreateDialog.show(); - }, name: 'Payment on account...', always: true} + { + name: 'Payment on account...', + always: true, + callback: () => { + this.setBalanceCreateDialog(); + this.$.balanceCreateDialog.show(); + } + } ]; } diff --git a/modules/ticket/front/main/index.html b/modules/ticket/front/main/index.html new file mode 100644 index 000000000..7e058f45d --- /dev/null +++ b/modules/ticket/front/main/index.html @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/ticket/front/main/index.js b/modules/ticket/front/main/index.js new file mode 100644 index 000000000..d6100daa3 --- /dev/null +++ b/modules/ticket/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Ticket extends ModuleMain {} + +ngModule.vnComponent('vnTicket', { + controller: Ticket, + template: require('./index.html') +}); diff --git a/modules/ticket/front/note/index.html b/modules/ticket/front/note/index.html index be2e683ce..617cf2f7d 100644 --- a/modules/ticket/front/note/index.html +++ b/modules/ticket/front/note/index.html @@ -16,7 +16,7 @@ data="observations" form="form"> -
        + diff --git a/modules/ticket/front/request/create/index.html b/modules/ticket/front/request/create/index.html index 9d7395312..46d96ca44 100644 --- a/modules/ticket/front/request/create/index.html +++ b/modules/ticket/front/request/create/index.html @@ -6,7 +6,7 @@ save="post"> -
        +
        - + @@ -295,7 +295,7 @@

        Destination ticket

        diff --git a/modules/ticket/front/tracking/edit/index.html b/modules/ticket/front/tracking/edit/index.html index 61647f669..3a1b13e50 100644 --- a/modules/ticket/front/tracking/edit/index.html +++ b/modules/ticket/front/tracking/edit/index.html @@ -4,7 +4,7 @@ data="$ctrl.params" form="form"> - + -
        - - - - - #{{id}} - {{nickname}} - - - - - - - - - - - {{firstName}} {{lastName}} - - - - - - - - - - - - -
        \ No newline at end of file +
        + + + + #{{id}} - {{nickname}} + + + + + + + + + + + {{firstName}} {{lastName}} + + + + + + + +
        + + + \ No newline at end of file diff --git a/modules/ticket/front/weekly/index/index.html b/modules/ticket/front/weekly/index/index.html index 585b14207..94621cc35 100644 --- a/modules/ticket/front/weekly/index/index.html +++ b/modules/ticket/front/weekly/index/index.html @@ -8,80 +8,78 @@ primary-key="ticketFk" auto-load="true"> -
        - - - + + + + + + + + + + Ticket ID + Client + Weekday + Warehouse + Salesperson + + + + + + + + {{weekly.ticketFk}} + + + + + {{::weekly.clientName}} + + + + + + + {{::weekly.warehouseName}} + + + {{::weekly.nickName}} + + + + + + + + + - - - - - - Ticket ID - Client - Weekday - Warehouse - Salesperson - - - - - - - - {{weekly.ticketFk}} - - - - - {{::weekly.clientName}} - - - - - - - {{::weekly.warehouseName}} - - - {{::weekly.nickName}} - - - - - - - - - - - -
        + @@ -101,5 +99,5 @@ vn-tooltip="Add weekly ticket" vn-bind="+" fixed-bottom-right> - + \ No newline at end of file diff --git a/modules/travel/front/basic-data/index.html b/modules/travel/front/basic-data/index.html index 557a243c7..85a5fad2b 100644 --- a/modules/travel/front/basic-data/index.html +++ b/modules/travel/front/basic-data/index.html @@ -5,7 +5,7 @@ form="form" save="patch"> -
        + - - - - -
        - + + + + + diff --git a/modules/travel/front/card/index.js b/modules/travel/front/card/index.js index 40d3c0f51..c3ad41702 100644 --- a/modules/travel/front/card/index.js +++ b/modules/travel/front/card/index.js @@ -1,20 +1,16 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -export default class Controller { - constructor($stateParams, $http) { - this.$http = $http; - this.$stateParams = $stateParams; - this.travel = null; - this.filter = { - where: {id: $stateParams.id}, +class Controller extends ModuleCard { + reload() { + let filter = { include: [ { relation: 'warehouseIn', scope: { fields: ['id', 'name'] } - }, - { + }, { relation: 'warehouseOut', scope: { fields: ['id', 'name'] @@ -22,24 +18,11 @@ export default class Controller { } ] }; - } - $onInit() { - this.getCard(); - } - - getCard() { - const params = {filter: this.filter}; - this.$http.get(`Travels/${this.$stateParams.id}`, {params}).then(response => { - this.travel = response.data; - }); - } - - reload() { - this.getCard(); + this.$http.get(`Travels/${this.$params.id}`, {filter}) + .then(response => this.travel = response.data); } } -Controller.$inject = ['$stateParams', '$http']; ngModule.component('vnTravelCard', { template: require('./index.html'), diff --git a/modules/travel/front/descriptor/index.js b/modules/travel/front/descriptor/index.js index 0739c4485..187a7ed8f 100644 --- a/modules/travel/front/descriptor/index.js +++ b/modules/travel/front/descriptor/index.js @@ -14,7 +14,7 @@ ngModule.component('vnTravelDescriptor', { travel: '<' }, require: { - card: '^vnTravelCard' + card: '^?vnTravelCard' }, controller: Controller }); diff --git a/modules/travel/front/index.js b/modules/travel/front/index.js index 1017a431b..d9e1fa07e 100644 --- a/modules/travel/front/index.js +++ b/modules/travel/front/index.js @@ -1,5 +1,6 @@ export * from './module'; +import './main'; import './index/'; import './search-panel'; import './descriptor'; diff --git a/modules/travel/front/index/index.html b/modules/travel/front/index/index.html index dc24e2738..1989a1262 100644 --- a/modules/travel/front/index/index.html +++ b/modules/travel/front/index/index.html @@ -1,65 +1,58 @@ - - + diff --git a/modules/travel/front/main/index.html b/modules/travel/front/main/index.html new file mode 100644 index 000000000..71b9462fe --- /dev/null +++ b/modules/travel/front/main/index.html @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/travel/front/main/index.js b/modules/travel/front/main/index.js new file mode 100644 index 000000000..3be713973 --- /dev/null +++ b/modules/travel/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Travel extends ModuleMain {} + +ngModule.vnComponent('vnTravel', { + controller: Travel, + template: require('./index.html') +}); diff --git a/modules/travel/front/routes.json b/modules/travel/front/routes.json index 55643c937..f540d532f 100644 --- a/modules/travel/front/routes.json +++ b/modules/travel/front/routes.json @@ -1,17 +1,24 @@ { "module": "travel", "name": "Travels", + "icon": "local_airport", "validations": true, "dependencies": ["worker"], - "menu": [ - {"state": "travel.card.basicData", "icon": "settings"}, - {"state": "travel.card.log", "icon": "history"}], + "menus": { + "main": [ + {"state": "travel.index", "icon": "local_airport"} + ], + "card": [ + {"state": "travel.card.basicData", "icon": "settings"}, + {"state": "travel.card.log", "icon": "history"} + ] + }, "routes": [ { "url": "/travel", "state": "travel", "abstract": true, - "component": "ui-view", + "component": "vn-travel", "description": "Travels" }, { "url": "/index?q", diff --git a/modules/worker/front/account/index.html b/modules/worker/front/account/index.html index 59c788312..f51876a07 100644 --- a/modules/worker/front/account/index.html +++ b/modules/worker/front/account/index.html @@ -10,7 +10,7 @@ data="user" form="form"> - + diff --git a/modules/worker/front/basic-data/index.html b/modules/worker/front/basic-data/index.html index b44b9ec91..1d0d705e7 100644 --- a/modules/worker/front/basic-data/index.html +++ b/modules/worker/front/basic-data/index.html @@ -6,7 +6,7 @@ url="Workers" save="post"> - + diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html index bcf4c44f2..3b361d6a6 100644 --- a/modules/worker/front/calendar/index.html +++ b/modules/worker/front/calendar/index.html @@ -3,20 +3,18 @@ data="absenceTypes" auto-load="true"> -
        -
        - - - - -
        +
        + + + +
        diff --git a/modules/worker/front/card/index.html b/modules/worker/front/card/index.html index 80f1f7a61..ba9c8ec53 100644 --- a/modules/worker/front/card/index.html +++ b/modules/worker/front/card/index.html @@ -1,7 +1,5 @@ - - - - - -
        -
        + + + + + diff --git a/modules/worker/front/card/index.js b/modules/worker/front/card/index.js index e149cb0d2..dd2a24448 100644 --- a/modules/worker/front/card/index.js +++ b/modules/worker/front/card/index.js @@ -1,19 +1,8 @@ import ngModule from '../module'; +import ModuleCard from 'salix/components/module-card'; -class Controller { - constructor($http, $stateParams) { - Object.assign(this, { - $http, - $stateParams, - }); - } - - $onInit() { - this.reload(); - } - +class Controller extends ModuleCard { reload() { - let query = `Workers/${this.$stateParams.id}`; let filter = { include: [ { @@ -27,8 +16,7 @@ class Controller { } } } - }, - { + }, { relation: 'sip', scope: { fields: ['extension', 'secret'] @@ -50,14 +38,11 @@ class Controller { ] }; - this.$http.get(query, {params: {filter}}).then(res => { - this.worker = res.data; - }); + this.$http.get(`Workers/${this.$params.id}`, {filter}) + .then(res => this.worker = res.data); } } -Controller.$inject = ['$http', '$stateParams']; - ngModule.component('vnWorkerCard', { template: require('./index.html'), controller: Controller diff --git a/modules/worker/front/department/index.html b/modules/worker/front/department/index.html index a464d59e0..e77d11e12 100644 --- a/modules/worker/front/department/index.html +++ b/modules/worker/front/department/index.html @@ -3,32 +3,29 @@ url="departments/getLeaves" auto-load="false"> -
        - - - - {{::item.name}} - - - - - - -
        +
        + + + {{::item.name}} + + + + + +
        - - + diff --git a/modules/worker/front/index/index.js b/modules/worker/front/index/index.js index 6a1c2f65c..81e9070bd 100644 --- a/modules/worker/front/index/index.js +++ b/modules/worker/front/index/index.js @@ -7,9 +7,6 @@ export default class Controller { $, selectedWorker: null, }); - this.moreOptions = [ - {callback: () => this.$state.go('worker.department'), name: 'Departments'} - ]; } onSearch(params) { @@ -22,9 +19,10 @@ export default class Controller { preview(event, worker) { if (event.defaultPrevented) return; event.preventDefault(); + event.stopPropagation(); + this.selectedWorker = worker; this.$.preview.show(); - event.stopImmediatePropagation(); } onMoreChange(callback) { diff --git a/modules/worker/front/main/index.html b/modules/worker/front/main/index.html new file mode 100644 index 000000000..826a7905f --- /dev/null +++ b/modules/worker/front/main/index.html @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/worker/front/main/index.js b/modules/worker/front/main/index.js new file mode 100644 index 000000000..d97a2d636 --- /dev/null +++ b/modules/worker/front/main/index.js @@ -0,0 +1,9 @@ +import ngModule from '../module'; +import ModuleMain from 'salix/components/module-main'; + +export default class Worker extends ModuleMain {} + +ngModule.vnComponent('vnWorker', { + controller: Worker, + template: require('./index.html') +}); diff --git a/modules/worker/front/pbx/index.html b/modules/worker/front/pbx/index.html index 70e67d6f9..5118d38ed 100644 --- a/modules/worker/front/pbx/index.html +++ b/modules/worker/front/pbx/index.html @@ -2,7 +2,7 @@ vn-id="watcher" data="$ctrl.worker.sip"> -
        + diff --git a/modules/worker/front/phones/index.html b/modules/worker/front/phones/index.html index 92930615b..95e0366c1 100644 --- a/modules/worker/front/phones/index.html +++ b/modules/worker/front/phones/index.html @@ -12,7 +12,7 @@ vn-id="watcher" data="$ctrl.phones"> - + -
        - - - - - -
        {{::$ctrl.weekdayNames[$index].name}}
        - {{::weekday.dated | date: 'dd'}} - - {{::weekday.dated | date: 'MMMM'}} - -
        -
        -
        - - - -
        - - - {{hour.timed | date: 'HH:mm'}} -
        -
        -
        -
        - - - - {{$ctrl.getWeekdayTotalHours(weekday)}} h. - - - - - - - - - -
        -
        - -
        -
        -
        Hours
        - - -
        - - + + + + + +
        {{::$ctrl.weekdayNames[$index].name}}
        + {{::weekday.dated | date: 'dd'}} + + {{::weekday.dated | date: 'MMMM'}} + +
        +
        +
        + + + +
        + + + {{hour.timed | date: 'HH:mm'}} +
        +
        +
        +
        + + + + {{$ctrl.getWeekdayTotalHours(weekday)}} h. + + + + + + + + + +
        +
        + +
        +
        +
        Hours
        + +
        - -
        + + +
        +