mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
Merge pull request #45 from Alfresco/development
Sync with latest development branch
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
FROM nginx
|
||||
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
WORKDIR /usr/share/nginx/html
|
||||
COPY dist/ .
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
version: '3.1'
|
||||
|
||||
services:
|
||||
app:
|
||||
image: 'alfresco/content-app'
|
||||
build: '.'
|
||||
ports:
|
||||
- 3000:80
|
||||
@@ -19,7 +19,7 @@ import { by, ElementFinder, promise } from 'protractor';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class LoginComponent extends Component {
|
||||
static selector = 'alfresco-login';
|
||||
static selector = 'adf-login';
|
||||
|
||||
private locators = {
|
||||
usernameInput: by.css('input#username'),
|
||||
|
||||
@@ -40,7 +40,10 @@ export class LoginPage extends Page {
|
||||
const { submitButton } = this.login;
|
||||
const hasSumbitButton = EC.presenceOf(submitButton);
|
||||
|
||||
return browser.wait(hasSumbitButton, BROWSER_WAIT_TIMEOUT);
|
||||
return browser.wait(hasSumbitButton, BROWSER_WAIT_TIMEOUT)
|
||||
.then(() => browser.executeScript('window.localStorage.clear();'))
|
||||
.then(() => browser.executeScript('window.sessionStorage.clear();'))
|
||||
.then(() => browser.driver.manage().deleteAllCookies());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { APP_ROUTES } from '../configs';
|
||||
export class LogoutPage extends Page {
|
||||
/** @override */
|
||||
constructor() {
|
||||
super(APP_ROUTES.LOGOUT);
|
||||
super(APP_ROUTES.LOGIN);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
import { browser, element, by, ElementFinder, promise } from 'protractor';
|
||||
|
||||
export abstract class Page {
|
||||
private static USE_HASH_STRATEGY = true;
|
||||
private static USE_HASH_STRATEGY = false;
|
||||
|
||||
private locators = {
|
||||
app: by.css('app-root'),
|
||||
|
||||
@@ -17,21 +17,24 @@
|
||||
|
||||
import { protractor, browser, by, ElementFinder } from 'protractor';
|
||||
|
||||
import { APP_ROUTES, BROWSER_WAIT_TIMEOUT } from '../../configs';
|
||||
import { APP_ROUTES, BROWSER_WAIT_TIMEOUT, SITE_VISIBILITY, SITE_ROLES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Create folder', () => {
|
||||
const username = 'jane.doe';
|
||||
const password = 'jane.doe';
|
||||
|
||||
const parent = 'parent-folder';
|
||||
const folderName1 = 'my-folder1';
|
||||
const folderName2 = 'my-folder2';
|
||||
const folderDescription = 'description of my folder';
|
||||
const duplicateFolderName = 'duplicate-folder-name';
|
||||
const nameWithSpaces = ' folder name ';
|
||||
const nameWithSpaces = ' folder-name ';
|
||||
|
||||
const siteName = 'site-private';
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
@@ -55,7 +58,10 @@ describe('Create folder', () => {
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username, password)
|
||||
.then(() => apis.user.nodes.createFolders([ duplicateFolderName ]))
|
||||
.then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE))
|
||||
.then(() => apis.admin.nodes.createFolders([ folderName1 ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.user.nodes.createFolders([ duplicateFolderName ], parent))
|
||||
.then(() => loginPage.load())
|
||||
.then(() => loginPage.loginWith(username, password))
|
||||
.then(done);
|
||||
@@ -74,80 +80,84 @@ describe('Create folder', () => {
|
||||
afterAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
apis.user.nodes.deleteNodes([
|
||||
folderName1,
|
||||
folderName2,
|
||||
duplicateFolderName,
|
||||
nameWithSpaces.trim()
|
||||
]),
|
||||
apis.user.nodes.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('option is enabled when having enough permissions', () => {
|
||||
personalFilesPage.sidenav.openNewMenu()
|
||||
.then((menu) => {
|
||||
const isEnabled = menu.getItemByLabel('Create folder').getWebElement().isEnabled();
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => personalFilesPage.sidenav.openNewMenu()
|
||||
.then((menu) => {
|
||||
const isEnabled = menu.getItemByLabel('Create folder').getWebElement().isEnabled();
|
||||
|
||||
expect(isEnabled).toBe(true, 'Create folder is not enabled');
|
||||
});
|
||||
expect(isEnabled).toBe(true, 'Create folder is not enabled');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('creates new folder with name', () => {
|
||||
openCreateDialog()
|
||||
.then(() => createDialog.enterName(folderName1).clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(folderName1).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => createDialog.enterName(folderName1).clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(folderName1).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('creates new folder with name and description', () => {
|
||||
openCreateDialog()
|
||||
.then(() => {
|
||||
createDialog
|
||||
.enterName(folderName2)
|
||||
.enterDescription(folderDescription)
|
||||
.clickCreate();
|
||||
})
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(folderName2).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
.then(() => {
|
||||
apis.user.nodes.getNodeDescription(folderName2)
|
||||
.then((description) => {
|
||||
expect(description).toEqual(folderDescription, 'Description is not correct');
|
||||
});
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => {
|
||||
createDialog
|
||||
.enterName(folderName2)
|
||||
.enterDescription(folderDescription)
|
||||
.clickCreate();
|
||||
})
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(folderName2).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
.then(() => {
|
||||
apis.user.nodes.getNodeDescription(folderName2)
|
||||
.then((description) => {
|
||||
expect(description).toEqual(folderDescription, 'Description is not correct');
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('enabled option tooltip', () => {
|
||||
personalFilesPage.sidenav.openNewMenu()
|
||||
.then(menu => {
|
||||
const action = browser.actions().mouseMove(menu.getItemByLabel('Create folder'));
|
||||
action.perform();
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => personalFilesPage.sidenav.openNewMenu()
|
||||
.then(menu => {
|
||||
const action = browser.actions().mouseMove(menu.getItemByLabel('Create folder'));
|
||||
action.perform();
|
||||
|
||||
return menu;
|
||||
})
|
||||
.then((menu) => {
|
||||
const tooltip = menu.getItemTooltip('Create folder');
|
||||
expect(tooltip).toContain('Create new folder');
|
||||
});
|
||||
return menu;
|
||||
})
|
||||
.then((menu) => {
|
||||
const tooltip = menu.getItemTooltip('Create folder');
|
||||
expect(tooltip).toContain('Create new folder');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('option is disabled when not enough permissions', () => {
|
||||
// refactor after implementing Breadcrumb automation component
|
||||
const breadcrumbRoot: ElementFinder = protractor.element(by.css('.adf-breadcrumb-item[title="User Homes"]'));
|
||||
const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES);
|
||||
|
||||
browser.actions().mouseMove(breadcrumbRoot).click().perform()
|
||||
.then(() => personalFilesPage.sidenav.openNewMenu())
|
||||
fileLibrariesPage.sidenav.navigateToLinkByLabel('File Libraries')
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(siteName))
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(folderName1))
|
||||
.then(() => fileLibrariesPage.sidenav.openNewMenu())
|
||||
.then(menu => {
|
||||
const isEnabled = menu.getItemByLabel('Create folder').getWebElement().isEnabled();
|
||||
expect(isEnabled).toBe(false, 'Create folder is not disabled');
|
||||
@@ -155,11 +165,12 @@ describe('Create folder', () => {
|
||||
});
|
||||
|
||||
it('disabled option tooltip', () => {
|
||||
// refactor after implementing Breadcrumb automation component
|
||||
const breadcrumbRoot: ElementFinder = protractor.element(by.css('.adf-breadcrumb-item[title="User Homes"]'));
|
||||
const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES);
|
||||
|
||||
browser.actions().mouseMove(breadcrumbRoot).click().perform()
|
||||
.then(() => personalFilesPage.sidenav.openNewMenu())
|
||||
fileLibrariesPage.sidenav.navigateToLinkByLabel('File Libraries')
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(siteName))
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(folderName1))
|
||||
.then(() => fileLibrariesPage.sidenav.openNewMenu())
|
||||
.then(menu => {
|
||||
const action = browser.actions().mouseMove(menu.getItemByLabel('Create folder'));
|
||||
action.perform()
|
||||
@@ -171,107 +182,123 @@ describe('Create folder', () => {
|
||||
});
|
||||
|
||||
it('dialog UI elements', () => {
|
||||
openCreateDialog().then(() => {
|
||||
const dialogTitle = createDialog.getTitle();
|
||||
const isFolderNameDisplayed = createDialog.nameInput.getWebElement().isDisplayed();
|
||||
const isDescriptionDisplayed = createDialog.descriptionTextArea.getWebElement().isDisplayed();
|
||||
const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
|
||||
const isCancelEnabled = createDialog.cancelButton.getWebElement().isEnabled();
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog().then(() => {
|
||||
const dialogTitle = createDialog.getTitle();
|
||||
const isFolderNameDisplayed = createDialog.nameInput.getWebElement().isDisplayed();
|
||||
const isDescriptionDisplayed = createDialog.descriptionTextArea.getWebElement().isDisplayed();
|
||||
const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
|
||||
const isCancelEnabled = createDialog.cancelButton.getWebElement().isEnabled();
|
||||
|
||||
expect(dialogTitle).toBe('Create new folder');
|
||||
expect(isFolderNameDisplayed).toBe(true, 'Name input is not displayed');
|
||||
expect(isDescriptionDisplayed).toBe(true, 'Description field is not displayed');
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(isCancelEnabled).toBe(true, 'Cancel button is not enabled');
|
||||
});
|
||||
expect(dialogTitle).toBe('Create new folder');
|
||||
expect(isFolderNameDisplayed).toBe(true, 'Name input is not displayed');
|
||||
expect(isDescriptionDisplayed).toBe(true, 'Description field is not displayed');
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(isCancelEnabled).toBe(true, 'Cancel button is not enabled');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with empty folder name', () => {
|
||||
openCreateDialog()
|
||||
.then(() => {
|
||||
createDialog.deleteNameWithBackspace();
|
||||
})
|
||||
.then(() => {
|
||||
const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => {
|
||||
createDialog.deleteNameWithBackspace();
|
||||
})
|
||||
.then(() => {
|
||||
const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is enabled');
|
||||
expect(validationMessage).toMatch('Folder name is required');
|
||||
});
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is enabled');
|
||||
expect(validationMessage).toMatch('Folder name is required');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with folder name ending with a dot "."', () => {
|
||||
openCreateDialog()
|
||||
.then(() => createDialog.enterName('folder-name.'))
|
||||
.then((dialog) => {
|
||||
const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = dialog.getValidationMessage();
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => createDialog.enterName('folder-name.'))
|
||||
.then((dialog) => {
|
||||
const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = dialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toMatch(`Folder name can't end with a period .`);
|
||||
});
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toMatch(`Folder name can't end with a period .`);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with folder name containing special characters', () => {
|
||||
const namesWithSpecialChars = [ 'a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ];
|
||||
|
||||
openCreateDialog()
|
||||
.then(() => {
|
||||
namesWithSpecialChars.forEach(name => {
|
||||
createDialog.enterName(name);
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => {
|
||||
namesWithSpecialChars.forEach(name => {
|
||||
createDialog.enterName(name);
|
||||
|
||||
const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
const isCreateEnabled = createDialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toContain(`Folder name can't contain these characters`);
|
||||
});
|
||||
});
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toContain(`Folder name can't contain these characters`);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with folder name containing only spaces', () => {
|
||||
openCreateDialog()
|
||||
.then(() => createDialog.enterName(' '))
|
||||
.then((dialog) => {
|
||||
const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = dialog.getValidationMessage();
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => createDialog.enterName(' '))
|
||||
.then((dialog) => {
|
||||
const isCreateEnabled = dialog.createButton.getWebElement().isEnabled();
|
||||
const validationMessage = dialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toMatch(`Folder name can't contain only spaces`);
|
||||
});
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toMatch(`Folder name can't contain only spaces`);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('cancel folder creation', () => {
|
||||
openCreateDialog()
|
||||
.then(() => {
|
||||
createDialog
|
||||
.enterName('test')
|
||||
.enterDescription('test description')
|
||||
.clickCancel();
|
||||
})
|
||||
.then(() => expect(createDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'));
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => {
|
||||
createDialog
|
||||
.enterName('test')
|
||||
.enterDescription('test description')
|
||||
.clickCancel();
|
||||
})
|
||||
.then(() => expect(createDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'))
|
||||
);
|
||||
});
|
||||
|
||||
it('duplicate folder name', () => {
|
||||
openCreateDialog()
|
||||
.then(() => createDialog.enterName(duplicateFolderName).clickCreate())
|
||||
.then(() => {
|
||||
personalFilesPage.getSnackBarMessage()
|
||||
.then(message => {
|
||||
expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
|
||||
expect(createDialog.component.isPresent()).toBe(true, 'dialog is not present');
|
||||
});
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => createDialog.enterName(duplicateFolderName).clickCreate())
|
||||
.then(() => {
|
||||
personalFilesPage.getSnackBarMessage()
|
||||
.then(message => {
|
||||
expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
|
||||
expect(createDialog.component.isPresent()).toBe(true, 'dialog is not present');
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('trim ending spaces from folder name', () => {
|
||||
openCreateDialog()
|
||||
.then(() => createDialog.enterName(nameWithSpaces).clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(nameWithSpaces.trim()).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => openCreateDialog()
|
||||
.then(() => createDialog.enterName(nameWithSpaces).clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(nameWithSpaces.trim()).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,12 +20,13 @@ import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { APP_ROUTES, SITE_VISIBILITY, SITE_ROLES } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Edit folder', () => {
|
||||
const username = 'jane.doe';
|
||||
const password = 'jane.doe';
|
||||
const username = 'john.doe';
|
||||
const password = 'john.doe';
|
||||
|
||||
const parent = 'parent-folder';
|
||||
const folderName = 'my-folder';
|
||||
const folderDescription = 'my folder description';
|
||||
|
||||
@@ -44,7 +45,7 @@ describe('Edit folder', () => {
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const personalFilesPage = new BrowsingPage();
|
||||
const personalFilesPage = new BrowsingPage(APP_ROUTES.PERSONAL_FILES);
|
||||
const editDialog = new CreateOrEditFolderDialog();
|
||||
const dataTable = personalFilesPage.dataTable;
|
||||
const editButton = personalFilesPage.toolbar.actions.getButtonByTitleAttribute('Edit');
|
||||
@@ -58,11 +59,11 @@ describe('Edit folder', () => {
|
||||
])
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => Promise.all([
|
||||
apis.user.nodes.createNodeWithProperties( folderName, '', folderDescription ),
|
||||
apis.user.nodes.createFolders([ folderNameToEdit, duplicateFolderName ]),
|
||||
apis.user.nodes.createNodeWithProperties( folderName, '', folderDescription, parent ),
|
||||
apis.user.nodes.createFolders([ folderNameToEdit, duplicateFolderName ], parent),
|
||||
loginPage.load()
|
||||
]))
|
||||
.then(() => { loginPage.loginWith(username, password); })
|
||||
.then(() => loginPage.loginWith(username, password))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
@@ -80,57 +81,63 @@ describe('Edit folder', () => {
|
||||
Promise
|
||||
.all([
|
||||
apis.admin.sites.deleteSite(siteName, true),
|
||||
apis.user.nodes.deleteNodes([ folderName, folderNameEdited, duplicateFolderName ]),
|
||||
apis.user.nodes.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('button is enabled when having permissions', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => {
|
||||
expect(editButton.isEnabled()).toBe(true);
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => {
|
||||
expect(editButton.isEnabled()).toBe(true);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('dialog UI defaults', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
expect(editDialog.getTitle()).toBe('Edit folder');
|
||||
expect(editDialog.nameInput.getWebElement().getAttribute('value')).toBe(folderName);
|
||||
expect(editDialog.descriptionTextArea.getWebElement().getAttribute('value')).toBe(folderDescription);
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(true, 'upload button is not enabled');
|
||||
expect(editDialog.cancelButton.getWebElement().isEnabled()).toBe(true, 'cancel button is not enabled');
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
expect(editDialog.getTitle()).toBe('Edit folder');
|
||||
expect(editDialog.nameInput.getWebElement().getAttribute('value')).toBe(folderName);
|
||||
expect(editDialog.descriptionTextArea.getWebElement().getAttribute('value')).toBe(folderDescription);
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(true, 'upload button is not enabled');
|
||||
expect(editDialog.cancelButton.getWebElement().isEnabled()).toBe(true, 'cancel button is not enabled');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('folder properties are modified when pressing OK', () => {
|
||||
dataTable.clickOnRowByContainingText(folderNameToEdit)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
editDialog
|
||||
.enterName(folderNameEdited)
|
||||
.enterDescription(folderDescriptionEdited)
|
||||
.clickUpdate();
|
||||
})
|
||||
.then(() => editDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(folderNameEdited).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
.then(() => {
|
||||
apis.user.nodes.getNodeDescription(folderNameEdited)
|
||||
.then((description) => {
|
||||
expect(description).toEqual(folderDescriptionEdited);
|
||||
});
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderNameToEdit)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
editDialog
|
||||
.enterName(folderNameEdited)
|
||||
.enterDescription(folderDescriptionEdited)
|
||||
.clickUpdate();
|
||||
})
|
||||
.then(() => editDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowByContainingText(folderNameEdited).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
.then(() => {
|
||||
apis.user.nodes.getNodeDescription(folderNameEdited)
|
||||
.then((description) => {
|
||||
expect(description).toEqual(folderDescriptionEdited);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('button is not displayed when not enough permissions', () => {
|
||||
const fileLibrariesPage = new BrowsingPage();
|
||||
const fileLibrariesPage = new BrowsingPage(APP_ROUTES.FILE_LIBRARIES);
|
||||
|
||||
fileLibrariesPage.sidenav.navigateToLinkByLabel('File Libraries')
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnRowByContainingText(siteName))
|
||||
@@ -141,71 +148,85 @@ describe('Edit folder', () => {
|
||||
});
|
||||
|
||||
it('with empty folder name', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
editDialog.deleteNameWithBackspace();
|
||||
})
|
||||
.then(() => {
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
|
||||
expect(editDialog.getValidationMessage()).toMatch('Folder name is required');
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
editDialog.deleteNameWithBackspace();
|
||||
})
|
||||
.then(() => {
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
|
||||
expect(editDialog.getValidationMessage()).toMatch('Folder name is required');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with name with special characters', () => {
|
||||
const namesWithSpecialChars = [ 'a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ];
|
||||
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
namesWithSpecialChars.forEach(name => {
|
||||
editDialog.enterName(name);
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
namesWithSpecialChars.forEach(name => {
|
||||
editDialog.enterName(name);
|
||||
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not disabled');
|
||||
expect(editDialog.getValidationMessage()).toContain(`Folder name can't contain these characters`);
|
||||
});
|
||||
});
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not disabled');
|
||||
expect(editDialog.getValidationMessage()).toContain(`Folder name can't contain these characters`);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with name ending with a dot', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.nameInput.sendKeys('.'))
|
||||
.then(() => {
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
|
||||
expect(editDialog.getValidationMessage()).toMatch(`Folder name can't end with a period .`);
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.nameInput.sendKeys('.'))
|
||||
.then(() => {
|
||||
expect(editDialog.updateButton.getWebElement().isEnabled()).toBe(false, 'upload button is not enabled');
|
||||
expect(editDialog.getValidationMessage()).toMatch(`Folder name can't end with a period .`);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('Cancel button', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.clickCancel())
|
||||
.then(() => { expect(editDialog.component.isPresent()).not.toBe(true, 'dialog is not closed'); });
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.clickCancel())
|
||||
.then(() => {
|
||||
expect(editDialog.component.isPresent()).not.toBe(true, 'dialog is not closed');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('with duplicate folder name', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.enterName(duplicateFolderName).clickUpdate())
|
||||
.then(() => {
|
||||
personalFilesPage.getSnackBarMessage()
|
||||
.then(message => {
|
||||
expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
|
||||
expect(editDialog.component.isPresent()).toBe(true, 'dialog is not present');
|
||||
});
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.enterName(duplicateFolderName).clickUpdate())
|
||||
.then(() => {
|
||||
personalFilesPage.getSnackBarMessage()
|
||||
.then(message => {
|
||||
expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
|
||||
expect(editDialog.component.isPresent()).toBe(true, 'dialog is not present');
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('trim ending spaces', () => {
|
||||
dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.nameInput.sendKeys(' '))
|
||||
.then(() => editDialog.clickUpdate())
|
||||
.then(() => editDialog.waitForDialogToClose())
|
||||
.then(() => {
|
||||
expect(personalFilesPage.snackBar.isPresent()).not.toBe(true, 'notification appears');
|
||||
expect(dataTable.getRowByContainingText(folderName).isPresent()).toBe(true, 'Folder not displayed in list view');
|
||||
});
|
||||
personalFilesPage.dataTable.doubleClickOnRowByContainingText(parent)
|
||||
.then(() => dataTable.clickOnRowByContainingText(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.nameInput.sendKeys(' '))
|
||||
.then(() => editDialog.clickUpdate())
|
||||
.then(() => editDialog.waitForDialogToClose())
|
||||
.then(() => {
|
||||
expect(personalFilesPage.snackBar.isPresent()).not.toBe(true, 'notification appears');
|
||||
expect(dataTable.getRowByContainingText(folderName).isPresent()).toBe(true, 'Folder not displayed in list view');
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
|
||||
|
||||
import { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Page titles', () => {
|
||||
const loginPage = new LoginPage();
|
||||
@@ -65,7 +65,7 @@ describe('Page titles', () => {
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
|
||||
|
||||
import { APP_ROUTES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Login', () => {
|
||||
@@ -63,7 +63,7 @@ describe('Login', () => {
|
||||
|
||||
afterEach(done => {
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
|
||||
|
||||
import { APP_ROUTES, BROWSER_WAIT_TIMEOUT } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Logout', () => {
|
||||
@@ -48,7 +48,7 @@ describe('Logout', () => {
|
||||
|
||||
afterEach((done) => {
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
|
||||
|
||||
import { APP_ROUTES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Personal Files', () => {
|
||||
@@ -81,7 +81,7 @@ describe('Personal Files', () => {
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ describe('Personal Files', () => {
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
|
||||
|
||||
import { APP_ROUTES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Side navigation', () => {
|
||||
const loginPage = new LoginPage();
|
||||
@@ -38,7 +38,7 @@ describe('Side navigation', () => {
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser } from 'protractor';
|
||||
|
||||
import { APP_ROUTES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { LocalStorageUtility } from '../../utilities/local-storage';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient, NodeContentTree } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Pagination', () => {
|
||||
@@ -75,7 +75,7 @@ describe('Pagination', () => {
|
||||
afterAll(done => {
|
||||
logoutPage
|
||||
.load()
|
||||
.then(() => LocalStorageUtility.clear())
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(() => nodesApi.deleteNodes([ content.name ]))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { promise } from 'protractor';
|
||||
import { RepoApi } from '../repo-api';
|
||||
import { NodesApi } from '../nodes/nodes-api';
|
||||
import { RepoClient } from './../../repo-client';
|
||||
|
||||
export class FavoritesApi extends RepoApi {
|
||||
|
||||
addFavorite(api: RepoClient, nodeType: string, name: string): Promise<any> {
|
||||
return api.nodes.getNodeByPath(name)
|
||||
.then((response) => {
|
||||
const { id } = response.data.entry;
|
||||
return ([{
|
||||
target: {
|
||||
[nodeType]: {
|
||||
guid: id
|
||||
}
|
||||
}
|
||||
}]);
|
||||
})
|
||||
.then((data) => {
|
||||
return this.post(`/people/-me-/favorites`, { data });
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getFavorite(api: RepoClient, name: string): Promise<any> {
|
||||
return api.nodes.getNodeByPath(name)
|
||||
.then((response) => {
|
||||
const { id } = response.data.entry;
|
||||
return this.get(`/people/-me-/favorites/${id}`);
|
||||
})
|
||||
.catch((response) => Promise.resolve(response));
|
||||
}
|
||||
|
||||
removeFavorite(api: RepoClient, nodeType: string, name: string): Promise<any> {
|
||||
return api.nodes.getNodeByPath(name)
|
||||
.then((response) => {
|
||||
const { id } = response.data.entry;
|
||||
return this.delete(`/people/-me-/favorites/${id}`);
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,13 @@ import { RepoClientAuth, RepoClientConfig } from './repo-client-models';
|
||||
import { PeopleApi } from './apis/people/people-api';
|
||||
import { NodesApi } from './apis/nodes/nodes-api';
|
||||
import { SitesApi } from './apis/sites/sites-api';
|
||||
import { FavoritesApi } from './apis/favorites/favorites-api';
|
||||
|
||||
export class RepoClient {
|
||||
public people: PeopleApi = new PeopleApi(this.auth, this.config);
|
||||
public nodes: NodesApi = new NodesApi(this.auth, this.config);
|
||||
public sites: SitesApi = new SitesApi(this.auth, this.config);
|
||||
// public favorites: FavoritesApi = new FavoritesApi(this.auth, this.config);
|
||||
public favorites: FavoritesApi = new FavoritesApi(this.auth, this.config);
|
||||
// public shared: SharedLinksApi = new SharedLinksApi(this.auth, this.config);
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -17,18 +17,14 @@
|
||||
|
||||
import { browser, promise } from 'protractor';
|
||||
|
||||
declare var window;
|
||||
|
||||
export class LocalStorageUtility {
|
||||
static clear(): promise.Promise<any> {
|
||||
return browser.executeScript(() => {
|
||||
return window.localStorage.clear();
|
||||
});
|
||||
export class Utils {
|
||||
// generate a random value
|
||||
static random(): string {
|
||||
return Math.random().toString(36).substring(3, 10);
|
||||
}
|
||||
|
||||
static getTicket(): promise.Promise<any> {
|
||||
return browser.executeScript(() => {
|
||||
return window.localStorage.getItem('ticket-ECM');
|
||||
});
|
||||
// local storage
|
||||
static clearLocalStorage(): promise.Promise<any> {
|
||||
return browser.executeScript('window.localStorage.clear();');
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
gzip on;
|
||||
gzip_min_length 1000;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-16
@@ -6,6 +6,8 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve --open",
|
||||
"build": "ng build",
|
||||
"build:prod": "ng build --prod",
|
||||
"build:dev": "ng build && node postbuild-dev.js",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
@@ -24,17 +26,17 @@
|
||||
"@angular/platform-browser": "4.4.5",
|
||||
"@angular/platform-browser-dynamic": "4.4.5",
|
||||
"@angular/router": "4.4.5",
|
||||
"@ngx-translate/core": "7.0.0",
|
||||
"alfresco-js-api": "1.10.0-beta5",
|
||||
"@ngx-translate/core": "8.0.0",
|
||||
"alfresco-js-api": "1.10.0-beta6",
|
||||
"core-js": "^2.4.1",
|
||||
"hammerjs": "2.0.8",
|
||||
"ng2-alfresco-core": "1.10.0-beta5",
|
||||
"ng2-alfresco-datatable": "1.10.0-beta5",
|
||||
"ng2-alfresco-documentlist": "1.10.0-beta5",
|
||||
"ng2-alfresco-login": "1.10.0-beta5",
|
||||
"ng2-alfresco-search": "1.10.0-beta5",
|
||||
"ng2-alfresco-upload": "1.10.0-beta5",
|
||||
"ng2-alfresco-viewer": "1.10.0-beta5",
|
||||
"ng2-alfresco-core": "1.10.0-beta6",
|
||||
"ng2-alfresco-datatable": "1.10.0-beta6",
|
||||
"ng2-alfresco-documentlist": "1.10.0-beta6",
|
||||
"ng2-alfresco-login": "1.10.0-beta6",
|
||||
"ng2-alfresco-search": "1.10.0-beta6",
|
||||
"ng2-alfresco-upload": "1.10.0-beta6",
|
||||
"ng2-alfresco-viewer": "1.10.0-beta6",
|
||||
"pdfjs-dist": "1.8.557",
|
||||
"rxjs": "5.1.0",
|
||||
"wsrv": "0.2.2",
|
||||
@@ -44,14 +46,14 @@
|
||||
"@angular/cli": "1.4.7",
|
||||
"@angular/compiler-cli": "4.4.5",
|
||||
"@angular/language-service": "4.4.5",
|
||||
"@types/jasmine": "~2.5.53",
|
||||
"@types/jasminewd2": "~2.0.2",
|
||||
"@types/jasmine": "^2.5.53",
|
||||
"@types/jasminewd2": "^2.0.2",
|
||||
"@types/node": "~6.0.60",
|
||||
"codelyzer": "~3.2.0",
|
||||
"jasmine-core": "~2.6.2",
|
||||
"jasmine-reporters": "2.2.1",
|
||||
"jasmine-spec-reporter": "~4.1.0",
|
||||
"jasmine2-protractor-utils": "1.3.0",
|
||||
"jasmine-core": "^2.6.2",
|
||||
"jasmine-reporters": "^2.2.1",
|
||||
"jasmine-spec-reporter": "^4.1.0",
|
||||
"jasmine2-protractor-utils": "^1.3.0",
|
||||
"karma": "~1.7.0",
|
||||
"karma-chrome-launcher": "~2.1.1",
|
||||
"karma-cli": "~1.0.1",
|
||||
@@ -59,7 +61,7 @@
|
||||
"karma-jasmine": "~1.1.0",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"node-rest-client": "^3.1.0",
|
||||
"protractor": "~5.1.2",
|
||||
"protractor": "^5.1.2",
|
||||
"ts-node": "~3.2.0",
|
||||
"tslint": "~5.7.0",
|
||||
"typescript": "~2.3.3"
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var fs = require('fs');
|
||||
var config = require('./dist/app.config.json');
|
||||
|
||||
config.ecmHost = 'http://localhost:8080';
|
||||
|
||||
fs.writeFileSync(
|
||||
'./dist/app.config.json',
|
||||
JSON.stringify(config, null, 4)
|
||||
);
|
||||
+48
-43
@@ -8,49 +8,54 @@ const jasmineReporters = require('jasmine-reporters');
|
||||
const projectRoot = path.resolve(__dirname);
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./e2e/**/*.test.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome',
|
||||
chromeOptions: {
|
||||
prefs: {
|
||||
'credentials_enable_service': false
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./e2e/suites/authentication/*.test.ts',
|
||||
'./e2e/suites/list-views/*.test.ts',
|
||||
'./e2e/suites/application/page-titles.test.ts',
|
||||
'./e2e/suites/navigation/side-navigation.test.ts',
|
||||
'./e2e/suites/pagination/pagination.test.ts',
|
||||
'./e2e/suites/actions/*.test.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome',
|
||||
chromeOptions: {
|
||||
prefs: {
|
||||
'credentials_enable_service': false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:3000',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
plugins: [{
|
||||
package: 'jasmine2-protractor-utils',
|
||||
disableHTMLReport: false,
|
||||
disableScreenshot: false,
|
||||
screenshotOnExpectFailure: true,
|
||||
screenshotOnSpecFailure: false,
|
||||
clearFoldersBeforeTest: true,
|
||||
htmlReportDir: `${projectRoot}/e2e-output/html-report/`,
|
||||
screenshotPath: `${projectRoot}/e2e-output/screenshots/`
|
||||
}],
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:3000',
|
||||
framework: 'jasmine2',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
plugins: [{
|
||||
package: 'jasmine2-protractor-utils',
|
||||
disableHTMLReport: false,
|
||||
disableScreenshot: false,
|
||||
screenshotOnExpectFailure: true,
|
||||
screenshotOnSpecFailure: false,
|
||||
clearFoldersBeforeTest: true,
|
||||
htmlReportDir: `${projectRoot}/e2e-output/html-report/`,
|
||||
screenshotPath: `${projectRoot}/e2e-output/screenshots/`
|
||||
}],
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
|
||||
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
|
||||
consolidateAll: true,
|
||||
savePath: `${projectRoot}/e2e-output/junit-report`,
|
||||
filePrefix: 'results.xml',
|
||||
useDotNotation: false,
|
||||
useFullTestName: false,
|
||||
reportFailedUrl: true
|
||||
}));
|
||||
}
|
||||
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
|
||||
consolidateAll: true,
|
||||
savePath: `${projectRoot}/e2e-output/junit-report`,
|
||||
filePrefix: 'results.xml',
|
||||
useDotNotation: false,
|
||||
useFullTestName: false,
|
||||
reportFailedUrl: true
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,7 +46,6 @@ import { SidenavComponent } from './components/sidenav/sidenav.component';
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(APP_ROUTES, {
|
||||
useHash: true,
|
||||
enableTracing: false // enable for debug only
|
||||
}),
|
||||
AdfModule,
|
||||
|
||||
@@ -23,10 +23,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { AdfModule } from '../adf.module';
|
||||
import { MaterialModule } from './material.module';
|
||||
|
||||
import { FolderDialogComponent } from './dialogs/folder-dialog.component';
|
||||
|
||||
import { FolderCreateDirective } from './directives/folder-create.directive';
|
||||
import { FolderEditDirective } from './directives/folder-edit.directive';
|
||||
import { NodeCopyDirective } from './directives/node-copy.directive';
|
||||
import { NodeDeleteDirective } from './directives/node-delete.directive';
|
||||
import { NodeMoveDirective } from './directives/node-move.directive';
|
||||
@@ -51,10 +47,6 @@ export function modules() {
|
||||
|
||||
export function declarations() {
|
||||
return [
|
||||
FolderDialogComponent,
|
||||
|
||||
FolderCreateDirective,
|
||||
FolderEditDirective,
|
||||
NodeCopyDirective,
|
||||
NodeDeleteDirective,
|
||||
NodeMoveDirective,
|
||||
@@ -77,9 +69,7 @@ export function providers() {
|
||||
@NgModule({
|
||||
imports: modules(),
|
||||
declarations: declarations(),
|
||||
entryComponents: [
|
||||
FolderDialogComponent
|
||||
],
|
||||
entryComponents: [],
|
||||
providers: providers(),
|
||||
exports: [
|
||||
...modules(),
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
<h2 mat-dialog-title>
|
||||
{{
|
||||
(editing
|
||||
? 'APP.FOLDER_DIALOG.EDIT_FOLDER_TITLE'
|
||||
: 'APP.FOLDER_DIALOG.CREATE_FOLDER_TITLE'
|
||||
) | translate
|
||||
}}
|
||||
</h2>
|
||||
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form" (submit)="submit()">
|
||||
<mat-form-field style="width: 100%">
|
||||
<input
|
||||
placeholder="{{ 'APP.FOLDER_DIALOG.FOLDER_NAME.LABEL' | translate }}"
|
||||
matInput
|
||||
required
|
||||
[formControl]="form.controls['name']"
|
||||
/>
|
||||
|
||||
<mat-hint *ngIf="form.controls['name'].dirty">
|
||||
<span *ngIf="form.controls['name'].errors?.required">
|
||||
{{ 'APP.FOLDER_DIALOG.FOLDER_NAME.ERRORS.REQUIRED' | translate }}
|
||||
</span>
|
||||
|
||||
<span *ngIf="!form.controls['name'].errors?.required && form.controls['name'].errors?.message">
|
||||
{{ form.controls['name'].errors?.message | translate }}
|
||||
</span>
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<mat-form-field style="width: 100%">
|
||||
<textarea
|
||||
matInput
|
||||
placeholder="{{ 'APP.FOLDER_DIALOG.FOLDER_DESCRIPTION.LABEL' | translate }}"
|
||||
rows="4"
|
||||
[formControl]="form.controls['description']"></textarea>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<button
|
||||
mat-raised-button
|
||||
(click)="submit()"
|
||||
[disabled]="!form.valid">
|
||||
{{
|
||||
(editing
|
||||
? 'APP.FOLDER_DIALOG.UPDATE_BUTTON.LABEL'
|
||||
: 'APP.FOLDER_DIALOG.CREATE_BUTTON.LABEL'
|
||||
) | translate
|
||||
}}
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-button
|
||||
mat-dialog-close>
|
||||
{{ 'APP.FOLDER_DIALOG.CANCEL_BUTTON.LABEL' | translate }}
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -1,260 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { MatDialogModule, MatDialogRef } from '@angular/material';
|
||||
import { CoreModule, NodesApiService, TranslationService, NotificationService } from 'ng2-alfresco-core';
|
||||
|
||||
import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing';
|
||||
import { FolderDialogComponent } from './folder-dialog.component';
|
||||
import { ComponentFixture } from '@angular/core/testing';
|
||||
|
||||
describe('FolderDialogComponent', () => {
|
||||
|
||||
let fixture: ComponentFixture<FolderDialogComponent>;
|
||||
let component: FolderDialogComponent;
|
||||
let translationService: TranslationService;
|
||||
let nodesApi: NodesApiService;
|
||||
let notificationService: NotificationService;
|
||||
let dialogRef;
|
||||
|
||||
beforeEach(async(() => {
|
||||
dialogRef = {
|
||||
close: jasmine.createSpy('close')
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule,
|
||||
MatDialogModule
|
||||
],
|
||||
declarations: [
|
||||
FolderDialogComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRef }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FolderDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
nodesApi = TestBed.get(NodesApiService);
|
||||
notificationService = TestBed.get(NotificationService);
|
||||
|
||||
translationService = TestBed.get(TranslationService);
|
||||
spyOn(translationService, 'get').and.returnValue(Observable.of('message'));
|
||||
});
|
||||
|
||||
describe('Edit', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.data = {
|
||||
folder: {
|
||||
id: 'node-id',
|
||||
name: 'folder-name',
|
||||
properties: {
|
||||
['cm:description']: 'folder-description'
|
||||
}
|
||||
}
|
||||
};
|
||||
component.ngOnInit();
|
||||
});
|
||||
|
||||
it('should init form with folder name and description', () => {
|
||||
expect(component.name).toBe('folder-name');
|
||||
expect(component.description).toBe('folder-description');
|
||||
});
|
||||
|
||||
it('should update form input', () => {
|
||||
component.form.controls['name'].setValue('folder-name-update');
|
||||
component.form.controls['description'].setValue('folder-description-update');
|
||||
|
||||
expect(component.name).toBe('folder-name-update');
|
||||
expect(component.description).toBe('folder-description-update');
|
||||
});
|
||||
|
||||
it('should submit updated values if form is valid', () => {
|
||||
spyOn(nodesApi, 'updateNode').and.returnValue(Observable.of({}));
|
||||
|
||||
component.form.controls['name'].setValue('folder-name-update');
|
||||
component.form.controls['description'].setValue('folder-description-update');
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(nodesApi.updateNode).toHaveBeenCalledWith(
|
||||
'node-id',
|
||||
{
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-name-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should call dialog to close with form data when submit is succesfluly', () => {
|
||||
const folder = {
|
||||
data: 'folder-data'
|
||||
};
|
||||
|
||||
spyOn(nodesApi, 'updateNode').and.returnValue(Observable.of(folder));
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(dialogRef.close).toHaveBeenCalledWith(folder);
|
||||
});
|
||||
|
||||
it('should not submit if form is invalid', () => {
|
||||
spyOn(nodesApi, 'updateNode');
|
||||
|
||||
component.form.controls['name'].setValue('');
|
||||
component.form.controls['description'].setValue('');
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(component.form.valid).toBe(false);
|
||||
expect(nodesApi.updateNode).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call dialog to close if submit fails', () => {
|
||||
spyOn(nodesApi, 'updateNode').and.returnValue(Observable.throw('error'));
|
||||
spyOn(component, 'handleError').and.callFake(val => val);
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(component.handleError).toHaveBeenCalled();
|
||||
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Create', () => {
|
||||
beforeEach(() => {
|
||||
component.data = {
|
||||
parentNodeId: 'parentNodeId',
|
||||
folder: null
|
||||
};
|
||||
component.ngOnInit();
|
||||
});
|
||||
|
||||
it('should init form with empty inputs', () => {
|
||||
expect(component.name).toBe('');
|
||||
expect(component.description).toBe('');
|
||||
});
|
||||
|
||||
it('should update form input', () => {
|
||||
component.form.controls['name'].setValue('folder-name-update');
|
||||
component.form.controls['description'].setValue('folder-description-update');
|
||||
|
||||
expect(component.name).toBe('folder-name-update');
|
||||
expect(component.description).toBe('folder-description-update');
|
||||
});
|
||||
|
||||
it('should submit updated values if form is valid', () => {
|
||||
spyOn(nodesApi, 'createFolder').and.returnValue(Observable.of({}));
|
||||
|
||||
component.form.controls['name'].setValue('folder-name-update');
|
||||
component.form.controls['description'].setValue('folder-description-update');
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(nodesApi.createFolder).toHaveBeenCalledWith(
|
||||
'parentNodeId',
|
||||
{
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-name-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should call dialog to close with form data when submit is succesfluly', () => {
|
||||
const folder = {
|
||||
data: 'folder-data'
|
||||
};
|
||||
|
||||
component.form.controls['name'].setValue('name');
|
||||
component.form.controls['description'].setValue('description');
|
||||
|
||||
spyOn(nodesApi, 'createFolder').and.returnValue(Observable.of(folder));
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(dialogRef.close).toHaveBeenCalledWith(folder);
|
||||
});
|
||||
|
||||
it('should not submit if form is invalid', () => {
|
||||
spyOn(nodesApi, 'createFolder');
|
||||
|
||||
component.form.controls['name'].setValue('');
|
||||
component.form.controls['description'].setValue('');
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(component.form.valid).toBe(false);
|
||||
expect(nodesApi.createFolder).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call dialog to close if submit fails', () => {
|
||||
spyOn(nodesApi, 'createFolder').and.returnValue(Observable.throw('error'));
|
||||
spyOn(component, 'handleError').and.callFake(val => val);
|
||||
|
||||
component.form.controls['name'].setValue('name');
|
||||
component.form.controls['description'].setValue('description');
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(component.handleError).toHaveBeenCalled();
|
||||
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleError()', () => {
|
||||
it('should raise error for 409', () => {
|
||||
spyOn(notificationService, 'openSnackMessage').and.stub();
|
||||
|
||||
const error = {
|
||||
message: '{ "error": { "statusCode" : 409 } }'
|
||||
};
|
||||
|
||||
component.handleError(error);
|
||||
|
||||
expect(notificationService.openSnackMessage).toHaveBeenCalled();
|
||||
expect(translationService.get).toHaveBeenCalledWith('APP.MESSAGES.ERRORS.EXISTENT_FOLDER');
|
||||
});
|
||||
|
||||
it('should raise generic error', () => {
|
||||
spyOn(notificationService, 'openSnackMessage').and.stub();
|
||||
|
||||
const error = {
|
||||
message: '{ "error": { "statusCode" : 123 } }'
|
||||
};
|
||||
|
||||
component.handleError(error);
|
||||
|
||||
expect(notificationService.openSnackMessage).toHaveBeenCalled();
|
||||
expect(translationService.get).toHaveBeenCalledWith('APP.MESSAGES.ERRORS.GENERIC');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,138 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { Component, Inject, Optional, OnInit } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
||||
import { TranslationService, NodesApiService, NotificationService } from 'ng2-alfresco-core';
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
|
||||
import { forbidSpecialCharacters, forbidEndingDot, forbidOnlySpaces } from './folder-name.validators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-folder-dialog',
|
||||
templateUrl: './folder-dialog.component.html'
|
||||
})
|
||||
export class FolderDialogComponent implements OnInit {
|
||||
form: FormGroup;
|
||||
folder: MinimalNodeEntryEntity = null;
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private dialog: MatDialogRef<FolderDialogComponent>,
|
||||
private nodesApi: NodesApiService,
|
||||
private translation: TranslationService,
|
||||
private notification: NotificationService,
|
||||
@Optional()
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: any
|
||||
) {}
|
||||
|
||||
get editing(): boolean {
|
||||
return !!this.data.folder;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const { folder } = this.data;
|
||||
let name = '', description = '';
|
||||
|
||||
if (folder) {
|
||||
const { properties } = folder;
|
||||
|
||||
name = folder.name || '';
|
||||
description = properties ? properties['cm:description'] : '';
|
||||
}
|
||||
|
||||
const validators = {
|
||||
name: [
|
||||
Validators.required,
|
||||
forbidSpecialCharacters,
|
||||
forbidEndingDot,
|
||||
forbidOnlySpaces
|
||||
]
|
||||
};
|
||||
|
||||
this.form = this.formBuilder.group({
|
||||
name: [ name, validators.name ],
|
||||
description: [ description ]
|
||||
});
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
const { name } = this.form.value;
|
||||
|
||||
return (name || '').trim();
|
||||
}
|
||||
|
||||
get description(): string {
|
||||
const { description } = this.form.value;
|
||||
|
||||
return (description || '').trim();
|
||||
}
|
||||
|
||||
private get properties(): any {
|
||||
const { name: title, description } = this;
|
||||
|
||||
return {
|
||||
'cm:title': title,
|
||||
'cm:description': description
|
||||
};
|
||||
}
|
||||
|
||||
private create(): Observable<MinimalNodeEntryEntity> {
|
||||
const { name, properties, nodesApi, data: { parentNodeId} } = this;
|
||||
return nodesApi.createFolder(parentNodeId, { name, properties });
|
||||
}
|
||||
|
||||
private edit(): Observable<MinimalNodeEntryEntity> {
|
||||
const { name, properties, nodesApi, data: { folder: { id: nodeId }} } = this;
|
||||
return nodesApi.updateNode(nodeId, { name, properties });
|
||||
}
|
||||
|
||||
submit() {
|
||||
const { form, dialog, editing } = this;
|
||||
|
||||
if (!form.valid) { return; }
|
||||
|
||||
(editing ? this.edit() : this.create())
|
||||
.subscribe(
|
||||
(folder: MinimalNodeEntryEntity) => dialog.close(folder),
|
||||
(error) => this.handleError(error)
|
||||
);
|
||||
}
|
||||
|
||||
handleError(error: any): any {
|
||||
let i18nMessageString = 'APP.MESSAGES.ERRORS.GENERIC';
|
||||
|
||||
try {
|
||||
const { error: { statusCode } } = JSON.parse(error.message);
|
||||
|
||||
if (statusCode === 409) {
|
||||
i18nMessageString = 'APP.MESSAGES.ERRORS.EXISTENT_FOLDER';
|
||||
}
|
||||
} catch (err) { /* Do nothing, keep the original message */ }
|
||||
|
||||
this.translation.get(i18nMessageString).subscribe(message => {
|
||||
this.notification.openSnackMessage(message, 3000);
|
||||
});
|
||||
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
const I18N_ERRORS_PATH = 'APP.FOLDER_DIALOG.FOLDER_NAME.ERRORS';
|
||||
|
||||
export function forbidSpecialCharacters({ value }: FormControl) {
|
||||
const specialCharacters: RegExp = /([\*\"\<\>\\\/\?\:\|])/;
|
||||
const isValid: boolean = !specialCharacters.test(value);
|
||||
|
||||
return (isValid) ? null : {
|
||||
message: `${I18N_ERRORS_PATH}.SPECIAL_CHARACTERS`
|
||||
};
|
||||
}
|
||||
|
||||
export function forbidEndingDot({ value }: FormControl) {
|
||||
const isValid: boolean = ((value || '').split('').pop() !== '.');
|
||||
|
||||
return isValid ? null : {
|
||||
message: `${I18N_ERRORS_PATH}.ENDING_DOT`
|
||||
};
|
||||
}
|
||||
|
||||
export function forbidOnlySpaces({ value }: FormControl) {
|
||||
const isValid: boolean = !!((value || '')).trim();
|
||||
|
||||
return isValid ? null : {
|
||||
message: `${I18N_ERRORS_PATH}.ONLY_SPACES`
|
||||
};
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { MatDialogModule, MatDialog } from '@angular/material';
|
||||
|
||||
import { FolderCreateDirective } from './folder-create.directive';
|
||||
import { ContentManagementService } from '../services/content-management.service';
|
||||
|
||||
@Component({
|
||||
template: '<div [app-create-folder]="parentNode"></div>'
|
||||
})
|
||||
class TestComponent {
|
||||
parentNode = '';
|
||||
}
|
||||
|
||||
describe('FolderCreateDirective', () => {
|
||||
let fixture: ComponentFixture<TestComponent>;
|
||||
let element;
|
||||
let node: any;
|
||||
let dialog: MatDialog;
|
||||
let contentService: ContentManagementService;
|
||||
let dialogRefMock;
|
||||
|
||||
const event: any = {
|
||||
type: 'click',
|
||||
preventDefault: () => null
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ MatDialogModule ],
|
||||
declarations: [
|
||||
TestComponent,
|
||||
FolderCreateDirective
|
||||
]
|
||||
,
|
||||
providers: [
|
||||
ContentManagementService
|
||||
]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
element = fixture.debugElement.query(By.directive(FolderCreateDirective));
|
||||
dialog = TestBed.get(MatDialog);
|
||||
contentService = TestBed.get(ContentManagementService);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
node = { entry: { id: 'nodeId' } };
|
||||
|
||||
dialogRefMock = {
|
||||
afterClosed: val => Observable.of(val)
|
||||
};
|
||||
|
||||
spyOn(dialog, 'open').and.returnValue(dialogRefMock);
|
||||
});
|
||||
|
||||
it('emits createFolder event when input value is not undefined', () => {
|
||||
spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(node));
|
||||
|
||||
contentService.createFolder.subscribe((val) => {
|
||||
expect(val).toBe(node);
|
||||
});
|
||||
|
||||
element.triggerEventHandler('click', event);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('does not emits createFolder event when input value is undefined', () => {
|
||||
spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(null));
|
||||
spyOn(contentService.createFolder, 'next');
|
||||
|
||||
element.triggerEventHandler('click', event);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(contentService.createFolder.next).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,66 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
import { MatDialog, MatDialogConfig } from '@angular/material';
|
||||
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
|
||||
import { FolderDialogComponent } from '../dialogs/folder-dialog.component';
|
||||
import { ContentManagementService } from '../services/content-management.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[app-create-folder]'
|
||||
})
|
||||
export class FolderCreateDirective {
|
||||
static DIALOG_WIDTH: number = 400;
|
||||
|
||||
@Input('app-create-folder')
|
||||
parentNodeId: string;
|
||||
|
||||
@HostListener('click', [ '$event' ])
|
||||
onClick(event) {
|
||||
event.preventDefault();
|
||||
this.openDialog();
|
||||
}
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialog,
|
||||
public content: ContentManagementService
|
||||
) {}
|
||||
|
||||
private get dialogConfig(): MatDialogConfig {
|
||||
const { DIALOG_WIDTH: width } = FolderCreateDirective;
|
||||
const { parentNodeId } = this;
|
||||
|
||||
return {
|
||||
data: { parentNodeId },
|
||||
width: `${width}px`
|
||||
};
|
||||
}
|
||||
|
||||
private openDialog(): void {
|
||||
const { dialogRef, dialogConfig, content } = this;
|
||||
const dialogInstance = dialogRef.open(FolderDialogComponent, dialogConfig);
|
||||
|
||||
dialogInstance.afterClosed().subscribe((node: MinimalNodeEntryEntity) => {
|
||||
if (node) {
|
||||
content.createFolder.next(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { MatDialogModule, MatDialog } from '@angular/material';
|
||||
|
||||
import { FolderEditDirective } from './folder-edit.directive';
|
||||
import { ContentManagementService } from '../services/content-management.service';
|
||||
|
||||
@Component({
|
||||
template: '<div [app-edit-folder]="folder"></div>'
|
||||
})
|
||||
class TestComponent {
|
||||
folder = {};
|
||||
}
|
||||
|
||||
describe('FolderEditDirective', () => {
|
||||
let fixture: ComponentFixture<TestComponent>;
|
||||
let element;
|
||||
let node: any;
|
||||
let dialog: MatDialog;
|
||||
let contentService: ContentManagementService;
|
||||
let dialogRefMock;
|
||||
|
||||
const event = {
|
||||
type: 'click',
|
||||
preventDefault: () => null
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ MatDialogModule ],
|
||||
declarations: [
|
||||
TestComponent,
|
||||
FolderEditDirective
|
||||
]
|
||||
,
|
||||
providers: [
|
||||
ContentManagementService
|
||||
]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
element = fixture.debugElement.query(By.directive(FolderEditDirective));
|
||||
dialog = TestBed.get(MatDialog);
|
||||
contentService = TestBed.get(ContentManagementService);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
node = { entry: { id: 'folderId' } };
|
||||
|
||||
dialogRefMock = {
|
||||
afterClosed: val => Observable.of(val)
|
||||
};
|
||||
|
||||
spyOn(dialog, 'open').and.returnValue(dialogRefMock);
|
||||
});
|
||||
|
||||
it('emits editFolder event when input value is not undefined', () => {
|
||||
spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(node));
|
||||
|
||||
contentService.createFolder.subscribe((val) => {
|
||||
expect(val).toBe(node);
|
||||
});
|
||||
|
||||
element.triggerEventHandler('click', event);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('does not emits FolderEditDirective event when input value is undefined', () => {
|
||||
spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(null));
|
||||
spyOn(contentService.createFolder, 'next');
|
||||
|
||||
element.triggerEventHandler('click', event);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(contentService.createFolder.next).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,67 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2017 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, HostListener, ElementRef, Input } from '@angular/core';
|
||||
import { MatDialog, MatDialogConfig } from '@angular/material';
|
||||
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
|
||||
import { FolderDialogComponent } from '../dialogs/folder-dialog.component';
|
||||
import { ContentManagementService } from '../services/content-management.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[app-edit-folder]'
|
||||
})
|
||||
export class FolderEditDirective {
|
||||
static DIALOG_WIDTH = 400;
|
||||
|
||||
@Input('app-edit-folder')
|
||||
folder: MinimalNodeEntryEntity;
|
||||
|
||||
@HostListener('click', [ '$event' ])
|
||||
onClick(event) {
|
||||
event.preventDefault();
|
||||
this.openDialog();
|
||||
}
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialog,
|
||||
public elementRef: ElementRef,
|
||||
public content: ContentManagementService
|
||||
) {}
|
||||
|
||||
private get dialogConfig(): MatDialogConfig {
|
||||
const { DIALOG_WIDTH: width } = FolderEditDirective;
|
||||
const { folder } = this;
|
||||
|
||||
return {
|
||||
data: { folder },
|
||||
width: `${width}px`
|
||||
};
|
||||
}
|
||||
|
||||
private openDialog(): void {
|
||||
const { dialogRef, dialogConfig, content } = this;
|
||||
const dialogInstance = dialogRef.open(FolderDialogComponent, dialogConfig);
|
||||
|
||||
dialogInstance.afterClosed().subscribe((node: MinimalNodeEntryEntity) => {
|
||||
if (node) {
|
||||
content.editFolder.next(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,8 @@
|
||||
import { Subject } from 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
|
||||
@Injectable()
|
||||
export class ContentManagementService {
|
||||
createFolder = new Subject<MinimalNodeEntryEntity>();
|
||||
editFolder = new Subject<MinimalNodeEntryEntity>();
|
||||
deleteNode = new Subject<string>();
|
||||
moveNode = new Subject<string>();
|
||||
restoreNode = new Subject<string>();
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
mat-icon-button
|
||||
*ngIf="canEditFolder(documentList.selection)"
|
||||
title="{{ 'APP.ACTIONS.EDIT' | translate }}"
|
||||
[app-edit-folder]="documentList.selection[0]?.entry">
|
||||
[adf-edit-folder]="documentList.selection[0]?.entry">
|
||||
<mat-icon>create</mat-icon>
|
||||
</button>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { CoreModule, NodesApiService, AlfrescoApiService } from 'ng2-alfresco-core';
|
||||
import { CoreModule, NodesApiService, AlfrescoApiService, AlfrescoContentService } from 'ng2-alfresco-core';
|
||||
import { CommonModule } from '../../common/common.module';
|
||||
|
||||
import { ContentManagementService } from '../../common/services/content-management.service';
|
||||
@@ -32,6 +32,7 @@ describe('Favorites Routed Component', () => {
|
||||
let component: FavoritesComponent;
|
||||
let nodesApi: NodesApiService;
|
||||
let alfrescoApi: AlfrescoApiService;
|
||||
let alfrescoContentService: AlfrescoContentService;
|
||||
let contentService: ContentManagementService;
|
||||
let router: Router;
|
||||
let page;
|
||||
@@ -80,6 +81,7 @@ describe('Favorites Routed Component', () => {
|
||||
|
||||
nodesApi = TestBed.get(NodesApiService);
|
||||
alfrescoApi = TestBed.get(AlfrescoApiService);
|
||||
alfrescoContentService = TestBed.get(AlfrescoContentService);
|
||||
contentService = TestBed.get(ContentManagementService);
|
||||
router = TestBed.get(Router);
|
||||
});
|
||||
@@ -94,7 +96,7 @@ describe('Favorites Routed Component', () => {
|
||||
spyOn(component, 'refresh');
|
||||
fixture.detectChanges();
|
||||
|
||||
contentService.editFolder.next(null);
|
||||
alfrescoContentService.folderEdit.next(null);
|
||||
|
||||
expect(component.refresh).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Router } from '@angular/router';
|
||||
import { Subscription } from 'rxjs/Rx';
|
||||
|
||||
import { MinimalNodeEntryEntity, PathElementEntity, PathInfo } from 'alfresco-js-api';
|
||||
import { NodesApiService } from 'ng2-alfresco-core';
|
||||
import { AlfrescoContentService, NodesApiService } from 'ng2-alfresco-core';
|
||||
import { DocumentListComponent } from 'ng2-alfresco-documentlist';
|
||||
|
||||
import { ContentManagementService } from '../../common/services/content-management.service';
|
||||
@@ -41,12 +41,13 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr
|
||||
constructor(
|
||||
private router: Router,
|
||||
private nodesApi: NodesApiService,
|
||||
private contentService: AlfrescoContentService,
|
||||
private content: ContentManagementService) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.onEditFolder = this.content.editFolder.subscribe(() => this.refresh());
|
||||
this.onEditFolder = this.contentService.folderEdit.subscribe(() => this.refresh());
|
||||
this.onMoveNode = this.content.moveNode.subscribe(() => this.refresh());
|
||||
this.onToggleFavorite = this.content.toggleFavorite
|
||||
.debounceTime(300).subscribe(() => this.refresh());
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
mat-icon-button
|
||||
*ngIf="canEditFolder(documentList.selection)"
|
||||
title="{{ 'APP.ACTIONS.EDIT' | translate }}"
|
||||
[app-edit-folder]="documentList.selection[0]?.entry">
|
||||
[adf-edit-folder]="documentList.selection[0]?.entry">
|
||||
<mat-icon>create</mat-icon>
|
||||
</button>
|
||||
|
||||
|
||||
@@ -170,13 +170,13 @@ describe('FilesComponent', () => {
|
||||
});
|
||||
|
||||
it('calls refresh onCreateFolder event', () => {
|
||||
contentManagementService.createFolder.next();
|
||||
alfrescoContentService.folderCreate.next();
|
||||
|
||||
expect(component.load).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls refresh editFolder event', () => {
|
||||
contentManagementService.editFolder.next();
|
||||
alfrescoContentService.folderEdit.next();
|
||||
|
||||
expect(component.load).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Observable, Subscription } from 'rxjs/Rx';
|
||||
import { Component, ViewChild, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
||||
import { Router, ActivatedRoute, Params } from '@angular/router';
|
||||
import { MinimalNodeEntity, MinimalNodeEntryEntity, PathElementEntity, NodePaging, PathElement } from 'alfresco-js-api';
|
||||
import { UploadService, FileUploadEvent, NodesApiService, AlfrescoContentService, AlfrescoApiService } from 'ng2-alfresco-core';
|
||||
@@ -60,7 +60,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const { route, contentManagementService, nodeActionsService, uploadService } = this;
|
||||
const { route, contentManagementService, contentService, nodeActionsService, uploadService } = this;
|
||||
const { data } = route.snapshot;
|
||||
|
||||
this.routeData = data;
|
||||
@@ -87,8 +87,8 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.onCopyNode = nodeActionsService.contentCopied
|
||||
.subscribe((nodes) => this.onContentCopied(nodes));
|
||||
this.onCreateFolder = contentManagementService.createFolder.subscribe(() => this.load());
|
||||
this.onEditFolder = contentManagementService.editFolder.subscribe(() => this.load());
|
||||
this.onCreateFolder = contentService.folderCreate.subscribe(() => this.load());
|
||||
this.onEditFolder = contentService.folderEdit.subscribe(() => this.load());
|
||||
this.onDeleteNode = contentManagementService.deleteNode.subscribe(() => this.load());
|
||||
this.onMoveNode = contentManagementService.moveNode.subscribe(() => this.load());
|
||||
this.onRestoreNode = contentManagementService.restoreNode.subscribe(() => this.load());
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
<mat-menu #menu="matMenu" [overlapTrigger]="false">
|
||||
<button
|
||||
mat-menu-item
|
||||
[app-create-folder]="node?.id"
|
||||
[disabled]="!canCreateContent(node)"
|
||||
[adf-create-folder]="node?.id"
|
||||
title="{{
|
||||
( canCreateContent(node)
|
||||
? 'APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER'
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Alfresco Content App</title>
|
||||
<base href="./">
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/png" href="favicon-96x96.png" sizes="96x96">
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
|
||||
"@angular-devkit/build-optimizer@~0.0.23":
|
||||
version "0.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.0.31.tgz#511bc00e18c787a6cd4efe37b8cdb9f1bc6d4472"
|
||||
version "0.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.0.32.tgz#1bf32332d8a7c84043059e3d265a52f9d11726fd"
|
||||
dependencies:
|
||||
loader-utils "^1.1.0"
|
||||
source-map "^0.5.6"
|
||||
@@ -18,13 +18,13 @@
|
||||
source-map "^0.5.6"
|
||||
|
||||
"@angular-devkit/schematics@~0.0.25":
|
||||
version "0.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.34.tgz#c3ef61b0e49e585d9982f2828e9a67b3879a6b1b"
|
||||
version "0.0.35"
|
||||
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.35.tgz#23dbe2c8dd430114a903a7995d6eefcf1f0f648d"
|
||||
dependencies:
|
||||
"@angular-devkit/core" "0.0.20"
|
||||
"@ngtools/json-schema" "^1.1.0"
|
||||
minimist "^1.2.0"
|
||||
rxjs "^5.4.2"
|
||||
rxjs "^5.5.2"
|
||||
|
||||
"@angular/animations@4.4.5":
|
||||
version "4.4.5"
|
||||
@@ -189,9 +189,9 @@
|
||||
magic-string "^0.22.3"
|
||||
source-map "^0.5.6"
|
||||
|
||||
"@ngx-translate/core@7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-7.0.0.tgz#5b6f63bd4042164d44cd85f68703af96e9392e7d"
|
||||
"@ngx-translate/core@8.0.0":
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-8.0.0.tgz#751fd6b512d80f3a748d2de8dfc96dfefa29afe0"
|
||||
|
||||
"@schematics/angular@~0.0.38":
|
||||
version "0.0.49"
|
||||
@@ -303,9 +303,9 @@ ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5:
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.3.0"
|
||||
|
||||
alfresco-js-api@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-1.10.0-beta5.tgz#6b3b111b1774b6b81a51f0ad0e5f7c24e5e234da"
|
||||
alfresco-js-api@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/alfresco-js-api/-/alfresco-js-api-1.10.0-beta6.tgz#c988a46f81ce17c70edd053d03b95d61ce5447f5"
|
||||
dependencies:
|
||||
event-emitter "0.3.4"
|
||||
superagent "3.7.0"
|
||||
@@ -887,8 +887,8 @@ caniuse-api@^1.5.2:
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
|
||||
version "1.0.30000756"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000756.tgz#e938a6b991630f30d2263dd3458beb65d362268b"
|
||||
version "1.0.30000758"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000758.tgz#a235627b1922e878b63164942c991b84de92c810"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
@@ -925,7 +925,7 @@ chalk@^1.1.1, chalk@^1.1.3:
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
|
||||
dependencies:
|
||||
@@ -1292,8 +1292,8 @@ cryptiles@3.x.x, cryptiles@^3.1.2:
|
||||
boom "5.x.x"
|
||||
|
||||
crypto-browserify@^3.11.0:
|
||||
version "3.11.1"
|
||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f"
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
||||
dependencies:
|
||||
browserify-cipher "^1.0.0"
|
||||
browserify-sign "^4.0.0"
|
||||
@@ -1305,6 +1305,7 @@ crypto-browserify@^3.11.0:
|
||||
pbkdf2 "^3.0.3"
|
||||
public-encrypt "^4.0.0"
|
||||
randombytes "^2.0.0"
|
||||
randomfill "^1.0.3"
|
||||
|
||||
css-color-names@0.0.4:
|
||||
version "0.0.4"
|
||||
@@ -1542,6 +1543,10 @@ detect-indent@^4.0.0:
|
||||
dependencies:
|
||||
repeating "^2.0.0"
|
||||
|
||||
detect-libc@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1"
|
||||
|
||||
detect-node@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127"
|
||||
@@ -3669,9 +3674,9 @@ negotiator@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
|
||||
|
||||
ng2-alfresco-core@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-core/-/ng2-alfresco-core-1.10.0-beta5.tgz#d641754b9440014a5b747811b82520c449f2694e"
|
||||
ng2-alfresco-core@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-core/-/ng2-alfresco-core-1.10.0-beta6.tgz#d1ed5028f3bb4e9c063e338290dfba9a9cb44992"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3685,8 +3690,8 @@ ng2-alfresco-core@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
core-js "2.4.1"
|
||||
hammerjs "2.0.8"
|
||||
moment "2.15.2"
|
||||
@@ -3695,9 +3700,9 @@ ng2-alfresco-core@1.10.0-beta5:
|
||||
systemjs "0.19.27"
|
||||
zone.js "0.8.12"
|
||||
|
||||
ng2-alfresco-datatable@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-datatable/-/ng2-alfresco-datatable-1.10.0-beta5.tgz#a63feac548ee5aac5ec677a923c84fbaecb3ba3c"
|
||||
ng2-alfresco-datatable@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-datatable/-/ng2-alfresco-datatable-1.10.0-beta6.tgz#37312c3be022b7eb893e4fa278c0177c77b9130f"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3710,19 +3715,19 @@ ng2-alfresco-datatable@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
core-js "2.4.1"
|
||||
hammerjs "2.0.8"
|
||||
ng2-alfresco-core "1.10.0-beta5"
|
||||
ng2-alfresco-core "1.10.0-beta6"
|
||||
reflect-metadata "0.1.10"
|
||||
rxjs "5.1.0"
|
||||
systemjs "0.19.27"
|
||||
zone.js "0.8.12"
|
||||
|
||||
ng2-alfresco-documentlist@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-documentlist/-/ng2-alfresco-documentlist-1.10.0-beta5.tgz#c63d5cb769c4ed5995179b883acf460c7bfb13a5"
|
||||
ng2-alfresco-documentlist@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-documentlist/-/ng2-alfresco-documentlist-1.10.0-beta6.tgz#512dd75fbef9df43949fa74665ccb831c3346b23"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3736,21 +3741,21 @@ ng2-alfresco-documentlist@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
core-js "2.4.1"
|
||||
hammerjs "2.0.8"
|
||||
ng2-alfresco-core "1.10.0-beta5"
|
||||
ng2-alfresco-datatable "1.10.0-beta5"
|
||||
ng2-alfresco-upload "1.10.0-beta5"
|
||||
ng2-alfresco-core "1.10.0-beta6"
|
||||
ng2-alfresco-datatable "1.10.0-beta6"
|
||||
ng2-alfresco-upload "1.10.0-beta6"
|
||||
reflect-metadata "0.1.10"
|
||||
rxjs "5.1.0"
|
||||
systemjs "0.19.27"
|
||||
zone.js "0.8.12"
|
||||
|
||||
ng2-alfresco-login@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-login/-/ng2-alfresco-login-1.10.0-beta5.tgz#fc54c6e6eb32774bb47e29654432209413993fe0"
|
||||
ng2-alfresco-login@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-login/-/ng2-alfresco-login-1.10.0-beta6.tgz#db18061d219362cf8533a49099b8aafa17c648d8"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3763,18 +3768,18 @@ ng2-alfresco-login@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
hammerjs "2.0.8"
|
||||
ng2-alfresco-core "1.10.0-beta5"
|
||||
ng2-alfresco-core "1.10.0-beta6"
|
||||
reflect-metadata "0.1.10"
|
||||
rxjs "5.1.0"
|
||||
systemjs "0.19.27"
|
||||
zone.js "0.8.12"
|
||||
|
||||
ng2-alfresco-search@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-search/-/ng2-alfresco-search-1.10.0-beta5.tgz#6a2c83c0bc9b3696908a53c3bf042cd1c7736127"
|
||||
ng2-alfresco-search@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-search/-/ng2-alfresco-search-1.10.0-beta6.tgz#6257100b8f52e5d812d4b8dae065b84124b636bb"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3787,21 +3792,21 @@ ng2-alfresco-search@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
core-js "2.4.1"
|
||||
hammerjs "2.0.8"
|
||||
ng2-alfresco-core "1.10.0-beta5"
|
||||
ng2-alfresco-datatable "1.10.0-beta5"
|
||||
ng2-alfresco-documentlist "1.10.0-beta5"
|
||||
ng2-alfresco-core "1.10.0-beta6"
|
||||
ng2-alfresco-datatable "1.10.0-beta6"
|
||||
ng2-alfresco-documentlist "1.10.0-beta6"
|
||||
reflect-metadata "0.1.10"
|
||||
rxjs "5.1.0"
|
||||
systemjs "0.19.27"
|
||||
zone.js "0.8.12"
|
||||
|
||||
ng2-alfresco-upload@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-upload/-/ng2-alfresco-upload-1.10.0-beta5.tgz#6d61b0777c6dd7703993ae04921dd44b78eb5bab"
|
||||
ng2-alfresco-upload@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-upload/-/ng2-alfresco-upload-1.10.0-beta6.tgz#7da94739cee61125dae4a4aa9c23573a414aa23e"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3814,20 +3819,20 @@ ng2-alfresco-upload@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
core-js "2.4.1"
|
||||
hammerjs "2.0.8"
|
||||
minimatch "3.0.4"
|
||||
ng2-alfresco-core "1.10.0-beta5"
|
||||
ng2-alfresco-core "1.10.0-beta6"
|
||||
reflect-metadata "0.1.10"
|
||||
rxjs "5.1.0"
|
||||
systemjs "0.19.27"
|
||||
zone.js "0.8.12"
|
||||
|
||||
ng2-alfresco-viewer@1.10.0-beta5:
|
||||
version "1.10.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-viewer/-/ng2-alfresco-viewer-1.10.0-beta5.tgz#b52a7afc89c6816ebe8def703aa8d879a38d3eb6"
|
||||
ng2-alfresco-viewer@1.10.0-beta6:
|
||||
version "1.10.0-beta6"
|
||||
resolved "https://registry.yarnpkg.com/ng2-alfresco-viewer/-/ng2-alfresco-viewer-1.10.0-beta6.tgz#04f9c400869e9e603acc47fc88b3ab3f5db2657b"
|
||||
dependencies:
|
||||
"@angular/animations" "4.4.5"
|
||||
"@angular/cdk" "2.0.0-beta.12"
|
||||
@@ -3840,11 +3845,11 @@ ng2-alfresco-viewer@1.10.0-beta5:
|
||||
"@angular/platform-browser" "4.4.5"
|
||||
"@angular/platform-browser-dynamic" "4.4.5"
|
||||
"@angular/router" "4.4.5"
|
||||
"@ngx-translate/core" "7.0.0"
|
||||
alfresco-js-api "1.10.0-beta5"
|
||||
"@ngx-translate/core" "8.0.0"
|
||||
alfresco-js-api "1.10.0-beta6"
|
||||
core-js "2.4.1"
|
||||
hammerjs "2.0.8"
|
||||
ng2-alfresco-core "1.10.0-beta5"
|
||||
ng2-alfresco-core "1.10.0-beta6"
|
||||
pdfjs-dist "1.5.404"
|
||||
reflect-metadata "0.1.10"
|
||||
rxjs "5.1.0"
|
||||
@@ -3929,9 +3934,10 @@ node-modules-path@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/node-modules-path/-/node-modules-path-1.0.1.tgz#40096b08ce7ad0ea14680863af449c7c75a5d1c8"
|
||||
|
||||
node-pre-gyp@^0.6.36:
|
||||
version "0.6.38"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.38.tgz#e92a20f83416415bb4086f6d1fb78b3da73d113d"
|
||||
version "0.6.39"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
|
||||
dependencies:
|
||||
detect-libc "^1.0.2"
|
||||
hawk "3.1.3"
|
||||
mkdirp "^0.5.1"
|
||||
nopt "^4.0.1"
|
||||
@@ -4524,8 +4530,8 @@ postcss-minify-selectors@^2.0.4:
|
||||
postcss-selector-parser "^2.0.0"
|
||||
|
||||
postcss-modules-extract-imports@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85"
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb"
|
||||
dependencies:
|
||||
postcss "^6.0.1"
|
||||
|
||||
@@ -4652,10 +4658,10 @@ postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.
|
||||
supports-color "^3.2.3"
|
||||
|
||||
postcss@^6.0.1:
|
||||
version "6.0.13"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f"
|
||||
version "6.0.14"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885"
|
||||
dependencies:
|
||||
chalk "^2.1.0"
|
||||
chalk "^2.3.0"
|
||||
source-map "^0.6.1"
|
||||
supports-color "^4.4.0"
|
||||
|
||||
@@ -4806,12 +4812,19 @@ randomatic@^1.1.3:
|
||||
is-number "^3.0.0"
|
||||
kind-of "^4.0.0"
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1:
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
randomfill@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.3.tgz#b96b7df587f01dd91726c418f30553b1418e3d62"
|
||||
dependencies:
|
||||
randombytes "^2.0.5"
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
|
||||
@@ -5064,7 +5077,7 @@ require-main-filename@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
|
||||
|
||||
requires-port@1.0.x, requires-port@1.x.x:
|
||||
requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
|
||||
@@ -5099,7 +5112,7 @@ rxjs@5.1.0:
|
||||
dependencies:
|
||||
symbol-observable "^1.0.1"
|
||||
|
||||
rxjs@^5.4.2:
|
||||
rxjs@^5.4.2, rxjs@^5.5.2:
|
||||
version "5.5.2"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3"
|
||||
dependencies:
|
||||
@@ -5863,8 +5876,8 @@ tslint@~5.7.0:
|
||||
tsutils "^2.8.1"
|
||||
|
||||
tsutils@^2.8.1:
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.12.1.tgz#f4d95ce3391c8971e46e54c4cf0edb0a21dd5b24"
|
||||
version "2.12.2"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.12.2.tgz#ad58a4865d17ec3ddb6631b6ca53be14a5656ff3"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
@@ -5987,11 +6000,11 @@ url-parse@1.0.x:
|
||||
requires-port "1.0.x"
|
||||
|
||||
url-parse@^1.1.8:
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.1.9.tgz#c67f1d775d51f0a18911dd7b3ffad27bb9e5bd19"
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986"
|
||||
dependencies:
|
||||
querystringify "~1.0.0"
|
||||
requires-port "1.0.x"
|
||||
requires-port "~1.0.0"
|
||||
|
||||
url@^0.11.0:
|
||||
version "0.11.0"
|
||||
@@ -6169,8 +6182,8 @@ webpack-dev-server@~2.7.1:
|
||||
yargs "^6.0.0"
|
||||
|
||||
webpack-merge@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.0.tgz#6ad72223b3e0b837e531e4597c199f909361511e"
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555"
|
||||
dependencies:
|
||||
lodash "^4.17.4"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user