Merge branch 'dev' into 7524-limitSelect
gitea/salix/pipeline/pr-dev This commit looks good
Details
gitea/salix/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
2aaad4316b
|
@ -24,6 +24,10 @@ module.exports = Self => {
|
|||
arg: 'lang',
|
||||
type: 'string',
|
||||
description: 'The user lang'
|
||||
}, {
|
||||
arg: 'twoFactor',
|
||||
type: 'string',
|
||||
description: 'The user twoFactor'
|
||||
}
|
||||
],
|
||||
http: {
|
||||
|
@ -32,8 +36,8 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.updateUser = async(ctx, id, name, nickname, email, lang) => {
|
||||
Self.updateUser = async(ctx, id, name, nickname, email, lang, twoFactor) => {
|
||||
await Self.userSecurity(ctx, id);
|
||||
await Self.upsertWithWhere({id}, {name, nickname, email, lang});
|
||||
await Self.upsertWithWhere({id}, {name, nickname, email, lang, twoFactor});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -101,9 +101,10 @@ module.exports = function(Self) {
|
|||
const headers = httpRequest.headers;
|
||||
const origin = headers.origin;
|
||||
|
||||
const defaultHash = '/reset-password?access_token=$token$';
|
||||
const defaultHash = '!/reset-password?access_token=$token$';
|
||||
const recoverHashes = {
|
||||
hedera: 'verificationToken=$token$'
|
||||
hedera: '!verificationToken=$token$',
|
||||
lilium: '/resetPassword?access_token=$token$'
|
||||
};
|
||||
|
||||
const app = info.options?.app;
|
||||
|
@ -115,7 +116,7 @@ module.exports = function(Self) {
|
|||
const params = {
|
||||
recipient: info.email,
|
||||
lang: user.lang,
|
||||
url: origin + '/#!' + recoverHash
|
||||
url: origin + '/#' + recoverHash
|
||||
};
|
||||
|
||||
const options = Object.assign({}, info.options);
|
||||
|
|
|
@ -3,4 +3,5 @@ apps:
|
|||
name: salix-back
|
||||
instances: 1
|
||||
max_restarts: 0
|
||||
autorestart: false
|
||||
node_args: --tls-min-v1.0 --openssl-legacy-provider
|
||||
|
|
|
@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_afterDelete`
|
|||
AFTER DELETE ON `ACL`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO ACL
|
||||
INSERT INTO ACLLog
|
||||
SET `action` = 'delete',
|
||||
`changedModel` = 'Acl',
|
||||
`changedModelId` = OLD.id,
|
||||
|
|
|
@ -21,6 +21,7 @@ BEGIN
|
|||
AND a.id IS NULL
|
||||
AND u.active
|
||||
AND c.created < util.VN_CURDATE() - INTERVAL vMonths MONTH
|
||||
AND NOT u.role = (SELECT id FROM `role` WHERE name = 'supplier')
|
||||
AND u.id NOT IN (
|
||||
SELECT DISTINCT c.id
|
||||
FROM client c
|
||||
|
|
|
@ -12,7 +12,7 @@ BEGIN
|
|||
DECLARE vSaleFk INT;
|
||||
DECLARE vSectorFk INT;
|
||||
DECLARE vSales CURSOR FOR
|
||||
SELECT s.id
|
||||
SELECT DISTINCT s.id
|
||||
FROM sectorCollectionSaleGroup sc
|
||||
JOIN saleGroupDetail sg ON sg.saleGroupFk = sc.saleGroupFk
|
||||
JOIN sale s ON sg.saleFk = s.id
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`host_beforeInsert`
|
||||
BEFORE INSERT ON `host`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`host_beforeUpdate`
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET new.updated = util.VN_NOW();
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE bi.Greuges_comercial_detail;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE vn.host ADD editorFk int(10) unsigned DEFAULT NULL NULL;
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE vn.item
|
||||
ADD CONSTRAINT item_itemPackingType_FK FOREIGN KEY (itemPackingTypeFk)
|
||||
REFERENCES vn.itemPackingType(code) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
@ -0,0 +1,9 @@
|
|||
ALTER TABLE hedera.tpvMerchantEnable
|
||||
DROP FOREIGN KEY tpvMerchantEnable_ibfk_1,
|
||||
DROP PRIMARY KEY,
|
||||
ADD CONSTRAINT tpvMerchantEnable_pk PRIMARY KEY (merchantFk),
|
||||
ADD CONSTRAINT tpvMerchantEnable_tpvMerchant_FK
|
||||
FOREIGN KEY (merchantFk)
|
||||
REFERENCES hedera.tpvMerchant(id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE;
|
|
@ -1,164 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account create and basic data path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('itManagement', 'account');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should open the new account form by clicking the add button', async() => {
|
||||
await page.waitToClick(selectors.accountIndex.addAccount);
|
||||
await page.waitForState('account.create');
|
||||
});
|
||||
|
||||
it('should fill the form and then save it by clicking the create button', async() => {
|
||||
await page.write(selectors.accountIndex.newName, 'remy');
|
||||
await page.write(selectors.accountIndex.newNickname, 'Gambit');
|
||||
await page.write(selectors.accountIndex.newEmail, 'RemyEtienneLeBeau@verdnatura.es');
|
||||
await page.autocompleteSearch(selectors.accountIndex.newRole, 'Trainee');
|
||||
await page.write(selectors.accountIndex.newPassword, 'cestlavie');
|
||||
await page.waitToClick(selectors.accountIndex.createAccountButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should redirect the user to the created account basic data section', async() => {
|
||||
await page.waitForState('account.card.basicData');
|
||||
});
|
||||
|
||||
it('should check the name is as expected', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.accountBasicData.name, 'value');
|
||||
|
||||
expect(result).toEqual('remy');
|
||||
});
|
||||
|
||||
it('should check the nickname is as expected', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.accountBasicData.nickname, 'value');
|
||||
|
||||
expect(result).toEqual('Gambit');
|
||||
});
|
||||
|
||||
it('should check the email is as expected', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.accountBasicData.email, 'value');
|
||||
|
||||
expect(result).toEqual('RemyEtienneLeBeau@verdnatura.es');
|
||||
});
|
||||
|
||||
it('should navigate to the roles section to check the roles are correct', async() => {
|
||||
await page.accessToSection('account.card.roles');
|
||||
const rolesCount = await page.countElement(selectors.accountRoles.anyResult);
|
||||
|
||||
expect(rolesCount).toEqual(3);
|
||||
});
|
||||
|
||||
describe('Descriptor option', () => {
|
||||
describe('activate account', () => {
|
||||
it(`should check the active account icon isn't present in the descriptor`, async() => {
|
||||
await page.waitForNumberOfElements(selectors.accountDescriptor.activeAccountIcon, 0);
|
||||
});
|
||||
|
||||
it('should activate the account using the descriptor menu', async() => {
|
||||
await page.waitToClick(selectors.accountDescriptor.menuButton);
|
||||
await page.waitToClick(selectors.accountDescriptor.activateAccount);
|
||||
await page.waitToClick(selectors.accountDescriptor.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Account enabled!');
|
||||
});
|
||||
|
||||
it('should check the active account icon is now present in the descriptor', async() => {
|
||||
await page.waitForSelector(selectors.accountDescriptor.activeAccountIcon, {visible: false});
|
||||
});
|
||||
});
|
||||
|
||||
describe('deactivate user', () => {
|
||||
it(`should check the inactive user icon isn't present in the descriptor just yet`, async() => {
|
||||
await page.waitForNumberOfElements(selectors.accountDescriptor.activeUserIcon, 0);
|
||||
});
|
||||
|
||||
it('should deactivate the user using the descriptor menu', async() => {
|
||||
await page.waitToClick(selectors.accountDescriptor.menuButton);
|
||||
await page.waitToClick(selectors.accountDescriptor.deactivateUser);
|
||||
await page.waitToClick(selectors.accountDescriptor.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('User deactivated!');
|
||||
});
|
||||
|
||||
it('should check the inactive user icon is now present', async() => {
|
||||
await page.waitForNumberOfElements(selectors.accountDescriptor.activeUserIcon, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('activate user', () => {
|
||||
it('should activate the user using the descriptor menu', async() => {
|
||||
await page.waitToClick(selectors.accountDescriptor.menuButton);
|
||||
await page.waitToClick(selectors.accountDescriptor.activateUser);
|
||||
await page.waitToClick(selectors.accountDescriptor.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('User activated!');
|
||||
});
|
||||
|
||||
it('should check the inactive user icon is not present anymore', async() => {
|
||||
await page.waitForNumberOfElements(selectors.accountDescriptor.activeUserIcon, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mail forwarding', () => {
|
||||
it('should activate the mail forwarding and set the recipent email', async() => {
|
||||
await page.accessToSection('account.card.mailForwarding');
|
||||
await page.waitToClick(selectors.accountMailForwarding.mailForwardingCheckbox);
|
||||
await page.write(selectors.accountMailForwarding.email, 'someEmail@someDomain.es');
|
||||
await page.waitToClick(selectors.accountMailForwarding.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Set password', () => {
|
||||
it('should set the password using the descriptor menu', async() => {
|
||||
const newPassword = 'quantum.12345';
|
||||
|
||||
await page.waitToClick(selectors.accountDescriptor.menuButton);
|
||||
await page.waitToClick(selectors.accountDescriptor.setPassword);
|
||||
await page.write(selectors.accountDescriptor.newPassword, newPassword);
|
||||
await page.write(selectors.accountDescriptor.repeatPassword, newPassword);
|
||||
await page.waitToClick(selectors.accountDescriptor.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Password changed succesfully!');
|
||||
});
|
||||
|
||||
// cant log into created account for unknown reasons
|
||||
// it('should login into the created account with the new password', async() => {
|
||||
// await page.loginAndModule('Remy', 'quantum.crypt0graphy');
|
||||
// });
|
||||
});
|
||||
|
||||
describe('delete account', () => {
|
||||
// it('should navigate to the account basic data section', async() => {
|
||||
// });
|
||||
|
||||
it('should delete the account using the descriptor menu', async() => {
|
||||
await page.waitToClick(selectors.accountDescriptor.menuButton);
|
||||
await page.waitToClick(selectors.accountDescriptor.deleteAccount);
|
||||
await page.waitToClick(selectors.accountDescriptor.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('User removed');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,66 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account Alias create and basic data path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('itManagement', 'account');
|
||||
await page.accessToSection('account.alias');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should open the new account alias form by clicking the add button', async() => {
|
||||
await page.waitToClick(selectors.accountAliasIndex.addAlias);
|
||||
await page.waitForState('account.alias.create');
|
||||
});
|
||||
|
||||
it('should fill the form and then save it by clicking the create alias button', async() => {
|
||||
await page.write(selectors.accountAliasIndex.newName, 'Boring alias');
|
||||
await page.write(selectors.accountAliasIndex.newDescription, 'Boring description');
|
||||
await page.waitToClick(selectors.accountAliasIndex.createAliasButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should redirect the user to the created account alias basic data section', async() => {
|
||||
await page.waitForState('account.alias.card.basicData');
|
||||
});
|
||||
|
||||
it('should edit the alias basic data', async() => {
|
||||
await page.overwrite(selectors.accountAliasBasicData.name, 'Psykers');
|
||||
await page.overwrite(selectors.accountAliasBasicData.description, 'Email group for psykers');
|
||||
await page.waitToClick(selectors.accountAliasBasicData.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the basicData section and check the name was edited successfully', async() => {
|
||||
await page.reloadSection('account.alias.card.basicData');
|
||||
const result = await page.waitToGetProperty(selectors.accountAliasBasicData.name, 'value');
|
||||
|
||||
expect(result).toEqual('Psykers');
|
||||
});
|
||||
|
||||
it('should check the alias description was edited successfully', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.accountAliasBasicData.description, 'value');
|
||||
|
||||
expect(result).toContain('psykers');
|
||||
});
|
||||
|
||||
it('should search IT alias then access the user section to check the role listed is the expected one', async() => {
|
||||
await page.accessToSearchResult('IT');
|
||||
await page.accessToSection('account.alias.card.users');
|
||||
const rolesCount = await page.countElement(selectors.accountAliasUsers.anyResult);
|
||||
|
||||
expect(rolesCount).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -1,86 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account Role create and basic data path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('it', 'account');
|
||||
await page.accessToSection('account.role');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should open the new account role form by clicking the add button', async() => {
|
||||
await page.waitToClick(selectors.accountRoleIndex.addRole);
|
||||
await page.waitForState('account.role.create');
|
||||
});
|
||||
|
||||
it('should fill the form and then save it by clicking the create role button', async() => {
|
||||
await page.write(selectors.accountRoleIndex.newName, 'boringRole');
|
||||
await page.write(selectors.accountRoleIndex.newDescription, 'Boring description');
|
||||
await page.waitToClick(selectors.accountRoleIndex.createRoleButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should redirect the user to the created role basic data section', async() => {
|
||||
await page.waitForState('account.role.card.basicData');
|
||||
});
|
||||
|
||||
it('should edit the role basic data', async() => {
|
||||
await page.overwrite(selectors.accountRoleBasicData.name, 'psyker');
|
||||
await page.overwrite(selectors.accountRoleBasicData.description, 'A role just for psykers');
|
||||
await page.waitToClick(selectors.accountRoleBasicData.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the role basicData section and check the name was edited successfully', async() => {
|
||||
await page.reloadSection('account.role.card.basicData');
|
||||
const result = await page.waitToGetProperty(selectors.accountRoleBasicData.name, 'value');
|
||||
|
||||
expect(result).toEqual('psyker');
|
||||
});
|
||||
|
||||
it('should check the role description was edited successfully', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.accountRoleBasicData.description, 'value');
|
||||
|
||||
expect(result).toContain('psykers');
|
||||
});
|
||||
|
||||
it('should navigate to the subroles section', async() => {
|
||||
await page.accessToSection('account.role.card.subroles');
|
||||
});
|
||||
|
||||
it('should asign a subrole', async() => {
|
||||
await page.waitToClick(selectors.accountSubroles.addSubrole);
|
||||
await page.autocompleteSearch(selectors.accountSubroles.role, 'teamManager');
|
||||
await page.waitToClick(selectors.accountSubroles.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Role added!');
|
||||
});
|
||||
|
||||
it('should reload the subroles section and check a role was added', async() => {
|
||||
await page.reloadSection('account.role.card.subroles');
|
||||
const subrolesCount = await page.countElement(selectors.accountSubroles.anyResult);
|
||||
|
||||
expect(subrolesCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should access the employee roles inheritance then check the roles listed are the expected ones', async() => {
|
||||
await page.accessToSearchResult('employee');
|
||||
await page.accessToSection('account.role.card.inherited');
|
||||
const rolesCount = await page.countElement(selectors.accountRoleInheritance.anyResult);
|
||||
|
||||
expect(rolesCount).toEqual(7);
|
||||
});
|
||||
});
|
|
@ -1,60 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account ACL path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('developer', 'account');
|
||||
await page.accessToSection('account.acl');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should go to create new acl', async() => {
|
||||
await page.waitToClick(selectors.accountAcl.addAcl);
|
||||
await page.waitForState('account.acl.create');
|
||||
});
|
||||
|
||||
it('should create new acl', async() => {
|
||||
await page.autocompleteSearch(selectors.accountAcl.role, 'sysadmin');
|
||||
await page.autocompleteSearch(selectors.accountAcl.model, 'Account');
|
||||
await page.autocompleteSearch(selectors.accountAcl.accessType, '*');
|
||||
await page.autocompleteSearch(selectors.accountAcl.permission, 'ALLOW');
|
||||
await page.waitToClick(selectors.accountAcl.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should navigate to edit', async() => {
|
||||
await page.doSearch();
|
||||
await page.waitToClick(selectors.accountAcl.thirdAcl);
|
||||
await page.waitForState('account.acl.edit');
|
||||
});
|
||||
|
||||
it('should edit the third acl', async() => {
|
||||
await page.autocompleteSearch(selectors.accountAcl.model, 'Supplier');
|
||||
await page.autocompleteSearch(selectors.accountAcl.accessType, 'READ');
|
||||
await page.waitToClick(selectors.accountAcl.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should delete the third result', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.accountAcl.thirdAcl, 'innerText');
|
||||
await page.waitToClick(selectors.accountAcl.deleteThirdAcl);
|
||||
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
const newResult = await page.waitToGetProperty(selectors.accountAcl.thirdAcl, 'innerText');
|
||||
|
||||
expect(message.text).toContain('ACL removed');
|
||||
expect(result).not.toEqual(newResult);
|
||||
});
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account Connections path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
const account = 'sysadmin';
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule(account, 'account');
|
||||
await page.accessToSection('account.connections');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should check this is the last connection', async() => {
|
||||
const firstResult = await page.waitToGetProperty(selectors.accountConnections.firstConnection, 'innerText');
|
||||
|
||||
expect(firstResult).toContain(account);
|
||||
});
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account Accounts path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('sysadmin', 'account');
|
||||
await page.accessToSection('account.accounts');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should sync roles', async() => {
|
||||
await page.waitToClick(selectors.accountAccounts.syncRoles);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Roles synchronized!');
|
||||
});
|
||||
|
||||
it('should relogin', async() => {
|
||||
await page.loginAndModule('sysadmin', 'account');
|
||||
await page.accessToSection('account.accounts');
|
||||
});
|
||||
|
||||
it('should sync all', async() => {
|
||||
await page.waitToClick(selectors.accountAccounts.syncAll);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Synchronizing in the background');
|
||||
});
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account LDAP path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('sysadmin', 'account');
|
||||
await page.accessToSection('account.ldap');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should set data and save', async() => {
|
||||
await page.waitToClick(selectors.accountLdap.checkEnable);
|
||||
await page.write(selectors.accountLdap.server, '1234');
|
||||
await page.write(selectors.accountLdap.rdn, '1234');
|
||||
await page.write(selectors.accountLdap.password, 'nightmare');
|
||||
await page.write(selectors.accountLdap.userDn, 'sysadmin');
|
||||
await page.write(selectors.accountLdap.groupDn, '1234');
|
||||
await page.waitToClick(selectors.accountLdap.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reset data', async() => {
|
||||
await page.waitToClick(selectors.accountLdap.checkEnable);
|
||||
await page.waitToClick(selectors.accountLdap.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account Samba path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('sysadmin', 'account');
|
||||
await page.accessToSection('account.samba');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should set data and save', async() => {
|
||||
await page.waitToClick(selectors.accountSamba.checkEnable);
|
||||
await page.write(selectors.accountSamba.adDomain, '1234');
|
||||
await page.write(selectors.accountSamba.adController, '1234');
|
||||
await page.write(selectors.accountSamba.adUser, 'sysadmin');
|
||||
await page.write(selectors.accountSamba.adPassword, 'nightmare');
|
||||
await page.write(selectors.accountSamba.userDn, 'testDn');
|
||||
await page.waitToClick(selectors.accountSamba.verifyCert);
|
||||
await page.waitToClick(selectors.accountSamba.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reset data', async() => {
|
||||
await page.waitToClick(selectors.accountSamba.checkEnable);
|
||||
await page.waitToClick(selectors.accountSamba.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
});
|
|
@ -1,112 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Account privileges path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('developer', 'account');
|
||||
await page.accessToSearchResult('1101');
|
||||
await page.accessToSection('account.card.privileges');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
describe('as developer', () => {
|
||||
it('should throw error when give privileges', async() => {
|
||||
await page.waitToClick(selectors.accountPrivileges.checkHasGrant);
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain(`You don't have grant privilege`);
|
||||
});
|
||||
|
||||
it('should throw error when change role', async() => {
|
||||
await page.autocompleteSearch(selectors.accountPrivileges.role, 'employee');
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain(`You don't have grant privilege`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('as sysadmin', () => {
|
||||
beforeAll(async() => {
|
||||
await page.loginAndModule('sysadmin', 'account');
|
||||
await page.accessToSearchResult('9');
|
||||
await page.accessToSection('account.card.privileges');
|
||||
});
|
||||
|
||||
it('should give privileges', async() => {
|
||||
await page.waitToClick(selectors.accountPrivileges.checkHasGrant);
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
await page.reloadSection('account.card.privileges');
|
||||
const result = await page.checkboxState(selectors.accountPrivileges.checkHasGrant);
|
||||
|
||||
expect(message.text).toContain(`Data saved!`);
|
||||
expect(result).toBe('checked');
|
||||
});
|
||||
|
||||
it('should throw error when change role and not own role', async() => {
|
||||
await page.autocompleteSearch(selectors.accountPrivileges.role, 'itBoss');
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain(`You don't own the role and you can't assign it to another user`);
|
||||
});
|
||||
|
||||
it('should change role to employee', async() => {
|
||||
await page.autocompleteSearch(selectors.accountPrivileges.role, 'employee');
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
await page.reloadSection('account.card.privileges');
|
||||
const result = await page.waitToGetProperty(selectors.accountPrivileges.role, 'value');
|
||||
|
||||
expect(message.text).toContain(`Data saved!`);
|
||||
expect(result).toContain('employee');
|
||||
});
|
||||
|
||||
it('should return role to developer', async() => {
|
||||
await page.autocompleteSearch(selectors.accountPrivileges.role, 'developer');
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
await page.reloadSection('account.card.privileges');
|
||||
const result = await page.waitToGetProperty(selectors.accountPrivileges.role, 'value');
|
||||
|
||||
expect(message.text).toContain(`Data saved!`);
|
||||
expect(result).toContain('developer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('as developer again', () => {
|
||||
it('should remove privileges', async() => {
|
||||
await page.accessToSearchResult('9');
|
||||
await page.accessToSection('account.card.privileges');
|
||||
|
||||
await page.waitToClick(selectors.accountPrivileges.checkHasGrant);
|
||||
await page.waitToClick(selectors.accountPrivileges.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain(`Data saved!`);
|
||||
});
|
||||
|
||||
it('should logIn in developer', async() => {
|
||||
await page.reloadSection('account.card.privileges');
|
||||
const result = await page.checkboxState(selectors.accountPrivileges.checkHasGrant);
|
||||
|
||||
expect(result).toBe('unchecked');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -38,7 +38,7 @@
|
|||
</vn-icon-button>
|
||||
</div>
|
||||
<a
|
||||
ui-sref="worker.card.summary({id: $root.user.id})"
|
||||
ng-click="$ctrl.redirect($root.user.id)"
|
||||
class="vn-button colored"
|
||||
translate>
|
||||
My account
|
||||
|
|
|
@ -82,6 +82,9 @@ class Controller {
|
|||
? {id: $search}
|
||||
: {bank: {like: '%' + $search + '%'}};
|
||||
}
|
||||
async redirect(id) {
|
||||
window.location.href = await this.vnConfig.vnApp.getUrl(`worker/${id}`);
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$translate', 'vnConfig', 'vnAuth', 'vnToken'];
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="AccountConfigs"
|
||||
data="$ctrl.config"
|
||||
id-value="1"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="watcher.submit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg" vn-focus>
|
||||
<vn-vertical>
|
||||
<vn-textfield
|
||||
label="Homedir base"
|
||||
ng-model="$ctrl.config.homedir"
|
||||
rule="AccountConfig">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Shell"
|
||||
ng-model="$ctrl.config.shell"
|
||||
rule="AccountConfig">
|
||||
</vn-textfield>
|
||||
<vn-input-number
|
||||
label="User and role base id"
|
||||
ng-model="$ctrl.config.idBase"
|
||||
rule="AccountConfig">
|
||||
</vn-input-number>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Min"
|
||||
ng-model="$ctrl.config.min"
|
||||
rule="AccountConfig">
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
label="Max"
|
||||
ng-model="$ctrl.config.max"
|
||||
rule="AccountConfig">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
label="Warn"
|
||||
ng-model="$ctrl.config.warn"
|
||||
rule="AccountConfig">
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
label="Inact"
|
||||
ng-model="$ctrl.config.inact"
|
||||
rule="AccountConfig">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
label="Synchronize all"
|
||||
ng-click="$ctrl.onSynchronizeAll()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Synchronize roles"
|
||||
ng-click="$ctrl.onSynchronizeRoles()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
disabled="!watcher.dataChanged()"
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,19 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
onSynchronizeAll() {
|
||||
this.vnApp.showSuccess(this.$t('Synchronizing in the background'));
|
||||
this.$http.patch(`Accounts/syncAll`);
|
||||
}
|
||||
|
||||
onSynchronizeRoles() {
|
||||
this.$http.patch(`RoleInherits/sync`)
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Roles synchronized!')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAccountAccounts', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,14 +0,0 @@
|
|||
Accounts: Cuentas
|
||||
Homedir base: Directorio base para carpetas de usuario
|
||||
Shell: Intérprete de línea de comandos
|
||||
User and role base id: Id base usuarios y roles
|
||||
Synchronize all: Sincronizar todo
|
||||
Synchronize roles: Sincronizar roles
|
||||
If password is not specified, just user attributes are synchronized: >-
|
||||
Si la contraseña no se especifica solo se sincronizarán lo atributos del usuario
|
||||
Synchronizing in the background: Sincronizando en segundo plano
|
||||
Users synchronized!: ¡Usuarios sincronizados!
|
||||
Username: Nombre de usuario
|
||||
Synchronize: Sincronizar
|
||||
Please enter the username: Por favor introduce el nombre de usuario
|
||||
Roles synchronized!: ¡Roles sincronizados!
|
|
@ -1,70 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="ACLs"
|
||||
data="$ctrl.acl"
|
||||
id-value="$ctrl.$params.id"
|
||||
insert-mode="!$ctrl.$params.id"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
vn-http-submit="watcher.submitGo('account.acl')"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
label="Role"
|
||||
ng-model="$ctrl.acl.principalId"
|
||||
url="VnRoles"
|
||||
id-field="name"
|
||||
value-field="name"
|
||||
vn-focus>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
label="Model"
|
||||
ng-model="$ctrl.acl.model"
|
||||
data="$ctrl.models"
|
||||
id-field="name"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
label="Property"
|
||||
ng-model="$ctrl.acl.property"
|
||||
info="Use * to match all properties">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
label="Access type"
|
||||
ng-model="$ctrl.acl.accessType"
|
||||
data="$ctrl.accessTypes"
|
||||
id-field="name"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
label="Permission"
|
||||
ng-model="$ctrl.acl.permission"
|
||||
data="$ctrl.permissions"
|
||||
id-field="name"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Cancel"
|
||||
ui-sref="account.acl">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,33 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.accessTypes = [
|
||||
{name: '*'},
|
||||
{name: 'READ'},
|
||||
{name: 'WRITE'}
|
||||
];
|
||||
this.permissions = [
|
||||
{name: 'ALLOW'},
|
||||
{name: 'DENY'}
|
||||
];
|
||||
|
||||
this.models = [];
|
||||
for (let model in window.validations)
|
||||
this.models.push({name: model});
|
||||
|
||||
this.acl = {
|
||||
property: '*',
|
||||
principalType: 'ROLE',
|
||||
accessType: 'READ',
|
||||
permission: 'ALLOW'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAclCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,4 +0,0 @@
|
|||
import './main';
|
||||
import './index/';
|
||||
import './create';
|
||||
import './search-panel';
|
|
@ -1,51 +0,0 @@
|
|||
<vn-auto-search
|
||||
model="model">
|
||||
</vn-auto-search>
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-w-sm">
|
||||
<vn-card>
|
||||
<vn-list class="separated">
|
||||
<a
|
||||
ng-repeat="row in model.data track by row.id"
|
||||
ui-sref="account.acl.edit(::{id: row.id})"
|
||||
translate-attr="{title: 'Edit ACL'}"
|
||||
class="vn-item search-result">
|
||||
<vn-item-section>
|
||||
<h6>{{::row.model}}.{{::row.property}}</h6>
|
||||
<vn-label-value
|
||||
label="Role"
|
||||
value="{{::row.principalId}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Access type"
|
||||
value="{{::row.accessType}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Permission"
|
||||
value="{{::row.permission}}">
|
||||
</vn-label-value>
|
||||
</vn-item-section>
|
||||
<vn-item-section side>
|
||||
<vn-icon-button
|
||||
vn-click-stop="deleteAcl.show(row)"
|
||||
vn-tooltip="Delete"
|
||||
icon="delete">
|
||||
</vn-icon-button>
|
||||
</vn-item-section>
|
||||
</a>
|
||||
</vn-list>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<a ui-sref="account.acl.create"
|
||||
vn-tooltip="New ACL"
|
||||
vn-bind="+"
|
||||
fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
<vn-confirm
|
||||
vn-id="deleteAcl"
|
||||
on-accept="$ctrl.onDelete($data)"
|
||||
question="Are you sure you want to continue?"
|
||||
message="ACL will be removed">
|
||||
</vn-confirm>
|
|
@ -1,15 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
onDelete(row) {
|
||||
return this.$http.delete(`ACLs/${row.id}`)
|
||||
.then(() => this.$.model.refresh())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('ACL removed')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAclIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,4 +0,0 @@
|
|||
New ACL: Nuevo ACL
|
||||
Edit ACL: Editar ACL
|
||||
ACL will be removed: El ACL será eliminado
|
||||
ACL removed: ACL eliminado
|
|
@ -1,4 +0,0 @@
|
|||
Model: Modelo
|
||||
Property: Propiedad
|
||||
Access type: Tipo de acceso
|
||||
Permission: Permiso
|
|
@ -1,20 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="ACLs"
|
||||
limit="20"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||
auto-save="true">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
info="Search ACL by model name"
|
||||
panel="vn-acl-search-panel"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||
base-state="account.acl"
|
||||
entity-state="edit">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<ui-view>
|
||||
<vn-acl-index></vn-acl-index>
|
||||
</ui-view>
|
|
@ -1,18 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import ModuleMain from 'salix/components/module-main';
|
||||
|
||||
export default class ACL extends ModuleMain {
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {model: {like: `%${value}%`}};
|
||||
default:
|
||||
return {[param]: value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnAclComponent', {
|
||||
controller: ACL,
|
||||
template: require('./index.html')
|
||||
});
|
|
@ -1,39 +0,0 @@
|
|||
<div class="search-panel">
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-vertical>
|
||||
<vn-autocomplete
|
||||
label="Role"
|
||||
ng-model="filter.principalId"
|
||||
url="VnRoles"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Model"
|
||||
ng-model="filter.model"
|
||||
data="$ctrl.models"
|
||||
id-field="name"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
label="Property"
|
||||
ng-model="filter.property">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
label="Access type"
|
||||
ng-model="filter.accessType"
|
||||
data="$ctrl.accessTypes"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Permission"
|
||||
ng-model="$ctrl.acl.permission"
|
||||
data="$ctrl.permissions"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
<vn-submit
|
||||
label="Search"
|
||||
class="vn-mt-lg">
|
||||
</vn-submit>
|
||||
</vn-vertical>
|
||||
</form>
|
||||
</div>
|
|
@ -1,26 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
export default class Controller extends SearchPanel {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.accessTypes = [
|
||||
{name: '*'},
|
||||
{name: 'READ'},
|
||||
{name: 'WRITE'}
|
||||
];
|
||||
this.permissions = [
|
||||
{name: 'ALLOW'},
|
||||
{name: 'DENY'}
|
||||
];
|
||||
|
||||
this.models = [];
|
||||
for (let model in window.validations)
|
||||
this.models.push({name: model});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAclSearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,43 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="MailAliases"
|
||||
data="$ctrl.alias"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="watcher.submit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
ng-model="$ctrl.alias.alias"
|
||||
rule="MailAlias"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Description"
|
||||
ng-model="$ctrl.alias.description"
|
||||
rule="MailAlias">
|
||||
</vn-textfield>
|
||||
<vn-check
|
||||
label="Public"
|
||||
ng-model="$ctrl.alias.isPublic"
|
||||
rule="MailAlias">
|
||||
</vn-check>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,12 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {}
|
||||
|
||||
ngModule.component('vnAliasBasicData', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
alias: '<'
|
||||
}
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
<vn-portal slot="menu">
|
||||
<vn-alias-descriptor alias="$ctrl.alias"></vn-alias-descriptor>
|
||||
<vn-left-menu source="alias"></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -1,14 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import ModuleCard from 'salix/components/module-card';
|
||||
|
||||
class Controller extends ModuleCard {
|
||||
reload() {
|
||||
this.$http.get(`MailAliases/${this.$params.id}`)
|
||||
.then(res => this.alias = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnAliasCard', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="MailAliases"
|
||||
data="$ctrl.alias"
|
||||
insert-mode="true"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
vn-http-submit="$ctrl.onSubmit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
ng-model="$ctrl.alias.alias"
|
||||
rule="MailAlias"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Description"
|
||||
ng-model="$ctrl.alias.description"
|
||||
rule="MailAlias">
|
||||
</vn-textfield>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Create">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Cancel"
|
||||
ui-sref="account.alias">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,15 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
onSubmit() {
|
||||
return this.$.watcher.submit().then(res =>
|
||||
this.$state.go('account.alias.card.basicData', {id: res.data.id})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAliasCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,27 +0,0 @@
|
|||
<vn-descriptor-content
|
||||
module="account"
|
||||
base-state="account.alias"
|
||||
description="$ctrl.alias.alias">
|
||||
<slot-menu>
|
||||
<vn-item
|
||||
ng-click="deleteAlias.show()"
|
||||
name="deleteAlias"
|
||||
translate>
|
||||
Delete
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value
|
||||
label="Description"
|
||||
value="{{$ctrl.alias.description}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
vn-id="delete-alias"
|
||||
on-accept="$ctrl.onDelete()"
|
||||
question="Are you sure you want to continue?"
|
||||
message="Alias will be removed">
|
||||
</vn-confirm>
|
|
@ -1,26 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
get alias() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set alias(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
onDelete() {
|
||||
return this.$http.delete(`MailAliases/${this.id}`)
|
||||
.then(() => this.$state.go('account.alias'))
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Alias removed')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAliasDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
alias: '<'
|
||||
}
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
Alias will be removed: El alias será eliminado
|
||||
Alias removed: Alias eliminado
|
|
@ -1,9 +0,0 @@
|
|||
import './main';
|
||||
import './index/';
|
||||
import './create';
|
||||
import './summary';
|
||||
import './card';
|
||||
import './descriptor';
|
||||
import './create';
|
||||
import './basic-data';
|
||||
import './users';
|
|
@ -1,39 +0,0 @@
|
|||
<vn-auto-search
|
||||
model="model">
|
||||
</vn-auto-search>
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-w-sm">
|
||||
<vn-card>
|
||||
<vn-list class="separated">
|
||||
<a
|
||||
ng-repeat="alias in model.data track by alias.id"
|
||||
ui-sref="account.alias.card.summary(::{id: alias.id})"
|
||||
ui-sref-opts="{inherit: false}"
|
||||
translate-attr="{title: 'View alias'}"
|
||||
class="vn-item search-result">
|
||||
<vn-item-section>
|
||||
<h6>{{::alias.alias}}</h6>
|
||||
<div>{{::alias.description}}</div>
|
||||
</vn-item-section>
|
||||
<vn-item-section side>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(alias)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-item-section>
|
||||
</a>
|
||||
</vn-list>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-alias-summary alias="$ctrl.selectedAlias"></vn-alias-summary>
|
||||
</vn-popup>
|
||||
<a ui-sref="account.alias.create"
|
||||
ui-sref-opts="{inherit: false}"
|
||||
vn-tooltip="New alias"
|
||||
vn-bind="+"
|
||||
fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
|
@ -1,14 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
preview(alias) {
|
||||
this.selectedAlias = alias;
|
||||
this.$.summary.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAliasIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
New alias: Nuevo alias
|
||||
View alias: Ver alias
|
|
@ -1 +0,0 @@
|
|||
Public: Público
|
|
@ -1,17 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="MailAliases"
|
||||
limit="20"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
info="Search alias by id or name"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||
base-state="account.alias">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<ui-view>
|
||||
<vn-alias-index></vn-alias-index>
|
||||
</ui-view>
|
|
@ -1,18 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import ModuleMain from 'salix/components/module-main';
|
||||
|
||||
export default class Alias extends ModuleMain {
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {alias: {like: `%${value}%`}};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnAlias', {
|
||||
controller: Alias,
|
||||
template: require('./index.html')
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
<vn-card class="summary">
|
||||
<h5>{{summary.alias}}</h5>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-one>
|
||||
<h4 translate>Basic data</h4>
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{summary.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Description"
|
||||
value="{{summary.description}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
|
@ -1,25 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from 'core/lib/component';
|
||||
|
||||
class Controller extends Component {
|
||||
set alias(value) {
|
||||
this._alias = value;
|
||||
this.$.summary = null;
|
||||
if (!value) return;
|
||||
|
||||
this.$http.get(`MailAliases/${value.id}`)
|
||||
.then(res => this.$.summary = res.data);
|
||||
}
|
||||
|
||||
get alias() {
|
||||
return this._alias;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAliasSummary', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
alias: '<'
|
||||
}
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
<vn-data-viewer
|
||||
data="data"
|
||||
class="vn-w-xs">
|
||||
<vn-card>
|
||||
<vn-table>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="row in data | orderBy:'user.name'">
|
||||
<vn-td>{{::row.user.name}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-icon-button
|
||||
icon="delete"
|
||||
translate-attr="{title: 'Remove'}"
|
||||
ng-click="removeConfirm.show(row)">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-confirm
|
||||
vn-id="removeConfirm"
|
||||
message="User will be removed from alias"
|
||||
question="Are you sure you want to continue?"
|
||||
on-accept="$ctrl.onRemove($data)">
|
||||
</vn-confirm>
|
|
@ -1,31 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
$onInit() {
|
||||
let filter = {
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
};
|
||||
this.$http.get(`MailAliases/${this.$params.id}/accounts`, {filter})
|
||||
.then(res => this.$.data = res.data);
|
||||
}
|
||||
|
||||
onRemove(row) {
|
||||
return this.$http.delete(`MailAliases/${this.$params.id}/accounts/${row.id}`)
|
||||
.then(() => {
|
||||
let index = this.$.data.indexOf(row);
|
||||
if (index !== -1) this.$.data.splice(index, 1);
|
||||
this.vnApp.showSuccess(this.$t('User removed'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAliasUsers', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnAliasUsers', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('account'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnAliasUsers', {$element: null});
|
||||
controller.$params.id = 1;
|
||||
}));
|
||||
|
||||
describe('$onInit()', () => {
|
||||
it('should delete entity and go to index', () => {
|
||||
$httpBackend.expectGET('MailAliases/1/accounts').respond('foo');
|
||||
controller.$onInit();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.data).toBe('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onRemove()', () => {
|
||||
it('should call backend method to change role', () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
controller.$.data = [
|
||||
{id: 1, alias: 'foo'},
|
||||
{id: 2, alias: 'bar'}
|
||||
];
|
||||
|
||||
$httpBackend.expectDELETE('MailAliases/1/accounts/1').respond();
|
||||
controller.onRemove(controller.$.data[0]);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.data).toEqual([{id: 2, alias: 'bar'}]);
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
User will be removed from alias: El usuario será borrado del alias
|
||||
User removed: Usuario borrado
|
|
@ -1,64 +0,0 @@
|
|||
<div ng-if="$ctrl.card.hasAccount">
|
||||
<vn-data-viewer
|
||||
data="data"
|
||||
class="vn-w-xs">
|
||||
<vn-card>
|
||||
<vn-list class="separated">
|
||||
<vn-item ng-repeat="row in data | orderBy:'alias.alias'">
|
||||
<vn-item-section>
|
||||
<div>
|
||||
{{::row.alias.alias}}
|
||||
</div>
|
||||
<div class="text-caption text-secondary">
|
||||
{{::row.alias.description}}
|
||||
</div>
|
||||
</vn-item-section>
|
||||
<vn-item-section side>
|
||||
<vn-icon-button
|
||||
icon="delete"
|
||||
translate-attr="{title: 'Unsubscribe'}"
|
||||
ng-click="removeConfirm.show(row)">
|
||||
</vn-icon-button>
|
||||
</vn-item-section>
|
||||
</vn-item>
|
||||
</vn-list>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-float-button
|
||||
icon="add"
|
||||
translate-attr="{title: 'Add'}"
|
||||
vn-bind="+"
|
||||
ng-click="$ctrl.onAddClick()"
|
||||
fixed-bottom-right>
|
||||
</vn-float-button>
|
||||
<vn-dialog
|
||||
vn-id="dialog"
|
||||
on-accept="$ctrl.onAddSave()">
|
||||
<tpl-body>
|
||||
<vn-autocomplete
|
||||
label="Alias"
|
||||
ng-model="$ctrl.addData.mailAlias"
|
||||
url="MailAliases"
|
||||
show-field="alias"
|
||||
vn-focus>
|
||||
</vn-autocomplete>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Save</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
<vn-confirm
|
||||
vn-id="removeConfirm"
|
||||
message="User will be removed from alias"
|
||||
question="Are you sure you want to continue?"
|
||||
on-accept="$ctrl.onRemove($data)">
|
||||
</vn-confirm>
|
||||
</div>
|
||||
<div
|
||||
ng-if="!$ctrl.card.hasAccount"
|
||||
class="bg-title"
|
||||
translate>
|
||||
Account not enabled
|
||||
</div>
|
|
@ -1,51 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
$onInit() {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
refresh() {
|
||||
let filter = {
|
||||
where: {account: this.$params.id},
|
||||
include: {
|
||||
relation: 'alias',
|
||||
scope: {
|
||||
fields: ['id', 'alias', 'description']
|
||||
}
|
||||
}
|
||||
};
|
||||
return this.$http.get(`MailAliasAccounts`, {filter})
|
||||
.then(res => this.$.data = res.data);
|
||||
}
|
||||
|
||||
onAddClick() {
|
||||
this.addData = {account: this.$params.id};
|
||||
this.$.dialog.show();
|
||||
}
|
||||
|
||||
onAddSave() {
|
||||
return this.$http.post(`MailAliasAccounts`, this.addData)
|
||||
.then(() => this.refresh())
|
||||
.then(() => this.vnApp.showSuccess(
|
||||
this.$t('Subscribed to alias!'))
|
||||
);
|
||||
}
|
||||
|
||||
onRemove(row) {
|
||||
return this.$http.delete(`MailAliasAccounts/${row.id}`)
|
||||
.then(() => {
|
||||
this.$.data.splice(this.$.data.indexOf(row), 1);
|
||||
this.vnApp.showSuccess(this.$t('Unsubscribed from alias!'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnUserAliases', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
card: '^vnUserCard'
|
||||
}
|
||||
});
|
|
@ -1,53 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnUserAliases', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('account'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnUserAliases', {$element: null});
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
}));
|
||||
|
||||
describe('refresh()', () => {
|
||||
it('should refresh the controller data', () => {
|
||||
$httpBackend.expectGET('MailAliasAccounts').respond('foo');
|
||||
controller.refresh();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.data).toBe('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onAddSave()', () => {
|
||||
it('should add the new row', () => {
|
||||
controller.addData = {account: 1};
|
||||
|
||||
$httpBackend.expectPOST('MailAliasAccounts').respond();
|
||||
$httpBackend.expectGET('MailAliasAccounts').respond('foo');
|
||||
controller.onAddSave();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onRemove()', () => {
|
||||
it('shoud remove the passed row remote and locally', () => {
|
||||
controller.$.data = [
|
||||
{id: 1, alias: 'foo'},
|
||||
{id: 2, alias: 'bar'}
|
||||
];
|
||||
|
||||
$httpBackend.expectDELETE('MailAliasAccounts/1').respond();
|
||||
controller.onRemove(controller.$.data[0]);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.data).toEqual([{id: 2, alias: 'bar'}]);
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
Unsubscribe: Desuscribir
|
||||
Subscribed to alias!: ¡Suscrito al alias!
|
||||
Unsubscribed from alias!: ¡Desuscrito del alias!
|
|
@ -1,51 +0,0 @@
|
|||
<mg-ajax path="VnUsers/{{patch.params.id}}/update-user" options="vnPatch"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.user"
|
||||
form="form"
|
||||
save="patch">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="$ctrl.onSubmit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-textfield
|
||||
label="User"
|
||||
ng-model="$ctrl.user.name"
|
||||
rule="VnUser"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Nickname"
|
||||
ng-model="$ctrl.user.nickname"
|
||||
rule="VnUser">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Personal email"
|
||||
ng-model="$ctrl.user.email"
|
||||
rule="VnUser">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
label="Language"
|
||||
ng-model="$ctrl.user.lang"
|
||||
url="Languages"
|
||||
value-field="code"
|
||||
rule="VnUser">
|
||||
</vn-autocomplete>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,25 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
$onInit() {
|
||||
if (this.$params.emailConfirmed)
|
||||
this.vnApp.showSuccess(this.$t('Email verified successfully!'));
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.submit()
|
||||
.then(() => this.card.reload());
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnUserBasicData', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
card: '^vnUserCard'
|
||||
},
|
||||
bindings: {
|
||||
user: '<'
|
||||
}
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
Email verified successfully!: Correo verificado correctamente!
|
|
@ -1,8 +0,0 @@
|
|||
<vn-portal slot="menu">
|
||||
<vn-user-descriptor
|
||||
user="$ctrl.user"
|
||||
on-change="$ctrl.reload()">
|
||||
</vn-user-descriptor>
|
||||
<vn-left-menu source="card"></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -1,32 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import ModuleCard from 'salix/components/module-card';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends ModuleCard {
|
||||
reload() {
|
||||
const filter = {
|
||||
where: {id: this.$params.id},
|
||||
include: {
|
||||
relation: 'role',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Promise.all([
|
||||
this.$http.get(`VnUsers/preview`, {filter})
|
||||
.then(res => {
|
||||
const [user] = res.data;
|
||||
this.user = user;
|
||||
}),
|
||||
this.$http.get(`Accounts/${this.$params.id}/exists`)
|
||||
.then(res => this.hasAccount = res.data.exists)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnUserCard', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,27 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnUserCard', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('account'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnUserCard', {$element: null});
|
||||
}));
|
||||
|
||||
describe('reload()', () => {
|
||||
it('should reload the controller data', () => {
|
||||
controller.$params.id = 1;
|
||||
|
||||
$httpBackend.expectGET('VnUsers/preview').respond('foo');
|
||||
$httpBackend.expectGET('Accounts/1/exists').respond({exists: true});
|
||||
controller.reload();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.user).toBe('f');
|
||||
expect(controller.hasAccount).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
.bg-title {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 24px;
|
||||
box-sizing: border-box;
|
||||
color: $color-font-secondary;
|
||||
font-size: 1.375rem;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="AccessTokens"
|
||||
filter="::$ctrl.filter"
|
||||
limit="20"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-w-sm">
|
||||
<vn-card>
|
||||
<vn-list class="separated">
|
||||
<a
|
||||
ng-repeat="row in model.data"
|
||||
ui-sref="account.card.summary(::{id: row.user.id})"
|
||||
translate-attr="{title: 'Go to user'}"
|
||||
class="vn-item search-result">
|
||||
<vn-item-section>
|
||||
<h6>{{::row.user.username}}</h6>
|
||||
<div>{{::row.created | date:'dd/MM HH:mm'}}</div>
|
||||
</vn-item-section>
|
||||
<vn-item-section side>
|
||||
<vn-icon-button
|
||||
vn-click-stop="disconnect.show(row)"
|
||||
vn-tooltip="Kill session"
|
||||
icon="exit_to_app">
|
||||
</vn-icon-button>
|
||||
</vn-item-section>
|
||||
</a>
|
||||
</vn-list>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-confirm
|
||||
vn-id="disconnect"
|
||||
on-accept="$ctrl.onDisconnect($data)"
|
||||
question="Are you sure you want to continue?"
|
||||
message="Session will be killed">
|
||||
</vn-confirm>
|
||||
<vn-float-button
|
||||
vn-tooltip="Refresh"
|
||||
icon="refresh"
|
||||
ng-click="model.refresh()"
|
||||
vn-bind="r"
|
||||
fixed-bottom-right>
|
||||
</vn-float-button>
|
|
@ -1,29 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.filter = {
|
||||
fields: ['id', 'created', 'userId'],
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['username']
|
||||
}
|
||||
},
|
||||
order: 'created DESC'
|
||||
};
|
||||
}
|
||||
|
||||
onDisconnect(row) {
|
||||
return this.$http.delete(`AccessTokens/${row.id}`)
|
||||
.then(() => this.$.model.refresh())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Session killed')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnConnections', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
Go to user: Ir al usuario
|
||||
Refresh: Actualizar
|
||||
Session will be killed: Se va a matar la sesión
|
||||
Kill session: Matar sesión
|
||||
Session killed: Sesión matada
|
|
@ -1,57 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="VnUsers"
|
||||
data="$ctrl.user"
|
||||
insert-mode="true"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
vn-http-submit="$ctrl.onSubmit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
ng-model="$ctrl.user.name"
|
||||
rule="VnUser"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Nickname"
|
||||
ng-model="$ctrl.user.nickname"
|
||||
rule="VnUser">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Email"
|
||||
ng-model="$ctrl.user.email"
|
||||
rule="VnUser">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
label="Role"
|
||||
ng-model="$ctrl.user.roleFk"
|
||||
url="VnRoles"
|
||||
rule="VnUser">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
label="Password"
|
||||
ng-model="$ctrl.user.password"
|
||||
type="password">
|
||||
</vn-textfield>
|
||||
<vn-check
|
||||
label="Active"
|
||||
ng-model="$ctrl.user.active">
|
||||
</vn-check>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
label="Create">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Cancel"
|
||||
ui-sref="account.index">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,20 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.user = {active: true};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
return this.$.watcher.submit().then(res => {
|
||||
this.$state.go('account.card.basicData', {id: res.data.id});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnUserCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`component vnUserDescriptor onPassChange() should throw an error when password is empty 1`] = `"You must enter a new password"`;
|
||||
|
||||
exports[`component vnUserDescriptor onPassChange() should throw an error when repeat password not matches new password 1`] = `"Passwords don't match"`;
|
|
@ -1,97 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnUserDescriptor', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
let user = {id: 1, name: 'foo'};
|
||||
|
||||
beforeEach(ngModule('account'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.whenGET('Accounts/1/exists').respond({exists: true});
|
||||
|
||||
controller = $componentController('vnUserDescriptor', {$element: null}, {user});
|
||||
jest.spyOn(controller, 'emit');
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
}));
|
||||
|
||||
describe('onDelete()', () => {
|
||||
it('should delete entity and go to index', () => {
|
||||
controller.$state.go = jest.fn();
|
||||
|
||||
$httpBackend.expectDELETE('VnUsers/1').respond();
|
||||
controller.onDelete();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('account.index');
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onPassChange()', () => {
|
||||
it('should throw an error when password is empty', () => {
|
||||
expect(() => {
|
||||
controller.onPassChange();
|
||||
}).toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
||||
it('should throw an error when repeat password not matches new password', () => {
|
||||
controller.newPassword = 'foo';
|
||||
controller.repeatPassword = 'bar';
|
||||
|
||||
expect(() => {
|
||||
controller.onPassChange();
|
||||
}).toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
||||
it('should make a request when password checks passes', () => {
|
||||
controller.newPassword = 'foo';
|
||||
controller.repeatPassword = 'foo';
|
||||
|
||||
$httpBackend.expectPATCH('Accounts/1/setPassword').respond();
|
||||
controller.onPassChange();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.emit).toHaveBeenCalledWith('change');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onEnableAccount()', () => {
|
||||
it('should make request to enable account', () => {
|
||||
$httpBackend.expectPOST('Accounts', {id: 1}).respond();
|
||||
controller.onEnableAccount();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.hasAccount).toBeTruthy();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.emit).toHaveBeenCalledWith('change');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onDisableAccount()', () => {
|
||||
it('should make request to disable account', () => {
|
||||
$httpBackend.expectDELETE('Accounts/1').respond();
|
||||
controller.onDisableAccount();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.hasAccount).toBeFalsy();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.emit).toHaveBeenCalledWith('change');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSetActive()', () => {
|
||||
it('should make request to activate/deactivate the user', () => {
|
||||
$httpBackend.expectPATCH('VnUsers/1', {active: true}).respond();
|
||||
controller.onSetActive(true);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.user.active).toBeTruthy();
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.emit).toHaveBeenCalledWith('change');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,24 +1,6 @@
|
|||
export * from './module';
|
||||
|
||||
import './main';
|
||||
import './index/';
|
||||
import './role';
|
||||
import './alias';
|
||||
import './connections';
|
||||
import './acl';
|
||||
import './summary';
|
||||
import './card';
|
||||
import './descriptor';
|
||||
import './descriptor-popover';
|
||||
import './search-panel';
|
||||
import './create';
|
||||
import './basic-data';
|
||||
import './mail-forwarding';
|
||||
import './aliases';
|
||||
import './roles';
|
||||
import './ldap';
|
||||
import './samba';
|
||||
import './accounts';
|
||||
import './privileges';
|
||||
import './user-log';
|
||||
import './role-log';
|
||||
import './summary';
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
<vn-auto-search
|
||||
model="model">
|
||||
</vn-auto-search>
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-w-sm">
|
||||
<vn-card>
|
||||
<div class="vn-list separated">
|
||||
<a
|
||||
ng-repeat="user in model.data track by user.id"
|
||||
ui-sref="account.card.summary(::{id: user.id})"
|
||||
translate-attr="{title: 'View user'}"
|
||||
class="vn-item search-result">
|
||||
<vn-item-section>
|
||||
<h6>{{::user.nickname}}</h6>
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{::user.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="User"
|
||||
value="{{::user.name}}">
|
||||
</vn-label-value>
|
||||
</vn-item-section>
|
||||
<vn-item-section side>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(user)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-item-section>
|
||||
</a>
|
||||
</div>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-user-summary user="$ctrl.selectedUser"></vn-user-summary>
|
||||
</vn-popup>
|
||||
<a
|
||||
fixed-bottom-right
|
||||
ui-sref="account.create"
|
||||
vn-tooltip="New user"
|
||||
vn-bind="+"
|
||||
vn-acl="itManagement"
|
||||
vn-acl-action="remove">
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
|
@ -1,14 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
preview(user) {
|
||||
this.selectedUser = user;
|
||||
this.$.summary.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnUserIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
New user: Nuevo usuario
|
||||
View user: Ver usuario
|
|
@ -1,66 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="LdapConfigs"
|
||||
data="$ctrl.config"
|
||||
id-value="1"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="watcher.submit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg" vn-focus>
|
||||
<vn-vertical>
|
||||
<vn-check
|
||||
label="Enable synchronization"
|
||||
ng-model="watcher.hasData">
|
||||
</vn-check>
|
||||
</vn-vertical>
|
||||
<vn-vertical
|
||||
ng-if="watcher.hasData"
|
||||
class="vn-mt-md">
|
||||
<vn-textfield
|
||||
label="Server"
|
||||
ng-model="$ctrl.config.server"
|
||||
rule="LdapConfig">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="RDN"
|
||||
ng-model="$ctrl.config.rdn"
|
||||
rule="LdapConfig">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Password"
|
||||
ng-model="$ctrl.config.password"
|
||||
type="password"
|
||||
rule="LdapConfig">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="User DN"
|
||||
ng-model="$ctrl.config.userDn"
|
||||
rule="LdapConfig">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Group DN"
|
||||
ng-model="$ctrl.config.groupDn"
|
||||
rule="LdapConfig">
|
||||
</vn-textfield>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
label="Test connection"
|
||||
ng-click="$ctrl.onTestConection()">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,14 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
onTestConection() {
|
||||
this.$http.get(`LdapConfigs/test`)
|
||||
.then(() => this.vnApp.showSuccess(this.$t('LDAP connection established!')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnAccountLdap', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
Enable synchronization: Habilitar sincronización
|
||||
Server: Servidor
|
||||
RDN: RDN
|
||||
User DN: DN usuarios
|
||||
Filter: Filtro
|
||||
Group DN: DN grupos
|
||||
Test connection: Probar conexión
|
||||
LDAP connection established!: ¡Conexión con LDAP establecida!
|
|
@ -1,49 +0,0 @@
|
|||
<div ng-if="$ctrl.card.hasAccount">
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="MailForwards"
|
||||
id-field="account"
|
||||
id-value="$ctrl.$params.id"
|
||||
data="data"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="watcher.submit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-check
|
||||
label="Enable mail forwarding"
|
||||
ng-model="watcher.hasData">
|
||||
</vn-check>
|
||||
<vn-textfield
|
||||
ng-if="watcher.hasData"
|
||||
label="Forward email"
|
||||
ng-model="data.forwardTo"
|
||||
info="All emails will be forwarded to the specified address."
|
||||
rule="MailForward"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
ng-if="!$ctrl.card.hasAccount"
|
||||
class="bg-title"
|
||||
translate>
|
||||
Account not enabled
|
||||
</div>
|
|
@ -1,12 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {}
|
||||
|
||||
ngModule.component('vnUserMailForwarding', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
card: '^vnUserCard'
|
||||
},
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
Mail forwarding: Reenvío de correo
|
||||
Forward email: Dirección de reenvío
|
||||
Enable mail forwarding: Habilitar redirección de correo
|
||||
All emails will be forwarded to the specified address.: >
|
||||
Todos los correos serán reenviados a la dirección especificada, no se
|
||||
mantendrá copia de los mismos en el buzón del usuario.
|
||||
You don't have enough privileges: No tienes suficientes permisos
|
|
@ -1,19 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="VnUsers/preview"
|
||||
filter="::$ctrl.filter"
|
||||
limit="20">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
vn-focus
|
||||
panel="vn-user-search-panel"
|
||||
info="Search user by id, name or nickname"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-portal slot="menu">
|
||||
<vn-left-menu></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -4,32 +4,10 @@ import ModuleMain from 'salix/components/module-main';
|
|||
export default class User extends ModuleMain {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.filter = {
|
||||
fields: ['id', 'nickname', 'name', 'role'],
|
||||
include: {
|
||||
relation: 'role',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {or: [
|
||||
{name: {like: `%${value}%`}},
|
||||
{nickname: {like: `%${value}%`}}
|
||||
]};
|
||||
case 'name':
|
||||
case 'nickname':
|
||||
return {[param]: {like: `%${value}%`}};
|
||||
case 'roleFk':
|
||||
return {[param]: value};
|
||||
}
|
||||
async $onInit() {
|
||||
this.$state.go('home');
|
||||
window.location.href = await this.vnApp.getUrl(`account/`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnUser', () => {
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('account'));
|
||||
|
||||
beforeEach(inject($componentController => {
|
||||
controller = $componentController('vnUser', {$element: null});
|
||||
}));
|
||||
|
||||
describe('exprBuilder()', () => {
|
||||
it('should search by id when only digits string is passed', () => {
|
||||
let expr = controller.exprBuilder('search', '1');
|
||||
|
||||
expect(expr).toEqual({id: '1'});
|
||||
});
|
||||
|
||||
it('should search by name when non-only digits string is passed', () => {
|
||||
let expr = controller.exprBuilder('search', '1foo');
|
||||
|
||||
expect(expr).toEqual({or: [
|
||||
{name: {like: '%1foo%'}},
|
||||
{nickname: {like: '%1foo%'}}
|
||||
]});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
<mg-ajax path="VnUsers/{{post.params.id}}/privileges" options="vnPost"></mg-ajax>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.user"
|
||||
form="form"
|
||||
save="post">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="watcher.submit()"
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-check
|
||||
label="Has grant"
|
||||
ng-model="$ctrl.user.hasGrant">
|
||||
</vn-check>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-card class="vn-pa-lg vn-mt-md">
|
||||
<vn-vertical>
|
||||
<vn-autocomplete
|
||||
label="Role"
|
||||
ng-model="$ctrl.user.roleFk"
|
||||
url="VnRoles">
|
||||
</vn-autocomplete>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,21 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
get user() {
|
||||
return this._user;
|
||||
}
|
||||
|
||||
set user(value) {
|
||||
this._user = value;
|
||||
if (!value) return;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnUserPrivileges', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
user: '<'
|
||||
}
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
Privileges: Privilegios
|
||||
Has grant: Puede delegar privilegios
|
|
@ -1 +0,0 @@
|
|||
<vn-log url="RoleLogs" origin-id="$ctrl.$params.id"></vn-log>
|
|
@ -1,7 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
ngModule.vnComponent('vnRoleLog', {
|
||||
template: require('./index.html'),
|
||||
controller: Section,
|
||||
});
|
|
@ -1,40 +0,0 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="VnRoles"
|
||||
data="$ctrl.role"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form
|
||||
name="form"
|
||||
ng-submit="watcher.submit()"
|
||||
|
||||
class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
ng-model="$ctrl.role.name"
|
||||
rule="VnRole.name"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
label="Description"
|
||||
ng-model="$ctrl.role.description"
|
||||
rule="VnRole.description"
|
||||
>
|
||||
</vn-textfield>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,12 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {}
|
||||
|
||||
ngModule.component('vnRoleBasicData', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
role: '<'
|
||||
}
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
<vn-portal slot="menu">
|
||||
<vn-role-descriptor role="$ctrl.role"></vn-role-descriptor>
|
||||
<vn-left-menu source="role"></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -1,14 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import ModuleCard from 'salix/components/module-card';
|
||||
|
||||
class Controller extends ModuleCard {
|
||||
reload() {
|
||||
this.$http.get(`VnRoles/${this.$params.id}`)
|
||||
.then(res => this.role = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnRoleCard', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('component vnRoleCard', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('account'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnRoleCard', {$element: null});
|
||||
}));
|
||||
|
||||
describe('reload()', () => {
|
||||
it('should reload the controller data', () => {
|
||||
controller.$params.id = 1;
|
||||
|
||||
$httpBackend.expectGET('VnRoles/1').respond('foo');
|
||||
controller.reload();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.role).toBe('foo');
|
||||
});
|
||||
});
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue