Commit 61795032 authored by Jeevan Shikaram's avatar Jeevan Shikaram Committed by Commit Bot

[App Management] Remove app management router.

This CL removes the existing App Management router and uses the existing
settings router.

Bug: 999443, 1009397
Change-Id: Ife6232a27fb042b26d0eec3582388a2e8fbcaa26
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1833393
Commit-Queue: Jeevan Shikaram <jshikaram@chromium.org>
Reviewed-by: default avatarcalamity <calamity@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704114}
parent 9815c28f
...@@ -22,7 +22,6 @@ js_type_check("closure_compile") { ...@@ -22,7 +22,6 @@ js_type_check("closure_compile") {
":pin_to_shelf_item", ":pin_to_shelf_item",
":pwa_permission_view", ":pwa_permission_view",
":reducers", ":reducers",
":router",
":store", ":store",
":store_client", ":store_client",
":toggle_row", ":toggle_row",
...@@ -61,7 +60,6 @@ js_library("app_management_page") { ...@@ -61,7 +60,6 @@ js_library("app_management_page") {
":actions", ":actions",
":browser_proxy", ":browser_proxy",
":main_view", ":main_view",
":router",
":store", ":store",
":store_client", ":store_client",
] ]
...@@ -74,6 +72,7 @@ js_library("app_permission_view") { ...@@ -74,6 +72,7 @@ js_library("app_permission_view") {
":dom_switch", ":dom_switch",
":pwa_permission_view", ":pwa_permission_view",
":store_client", ":store_client",
"../../..:route",
] ]
} }
...@@ -164,15 +163,6 @@ js_library("reducers") { ...@@ -164,15 +163,6 @@ js_library("reducers") {
] ]
} }
js_library("router") {
deps = [
":actions",
":constants",
":store_client",
"../../..:route",
]
}
js_library("store") { js_library("store") {
deps = [ deps = [
":reducers", ":reducers",
......
...@@ -39,19 +39,12 @@ cr.define('app_management.actions', function() { ...@@ -39,19 +39,12 @@ cr.define('app_management.actions', function() {
} }
/** /**
* @param {PageType} pageType * @param {?string} appId
* @param {string=} id
*/ */
function changePage(pageType, id) { function updateSelectedAppId(appId) {
if (pageType === PageType.DETAIL && !id) {
console.warn(
'Tried to load app detail page without providing an app id.');
}
return { return {
name: 'change-page', name: 'update-selected-app-id',
pageType: pageType, value: appId,
id: id,
}; };
} }
...@@ -71,7 +64,7 @@ cr.define('app_management.actions', function() { ...@@ -71,7 +64,7 @@ cr.define('app_management.actions', function() {
addApp: addApp, addApp: addApp,
changeApp: changeApp, changeApp: changeApp,
removeApp: removeApp, removeApp: removeApp,
changePage: changePage,
updateArcSupported: updateArcSupported, updateArcSupported: updateArcSupported,
updateSelectedAppId: updateSelectedAppId,
}; };
}); });
...@@ -23,8 +23,7 @@ Polymer({ ...@@ -23,8 +23,7 @@ Polymer({
* @private * @private
*/ */
onClick_: function() { onClick_: function() {
this.dispatch( app_management.util.openAppDetailPage(this.app.id);
app_management.actions.changePage(PageType.DETAIL, this.app.id));
}, },
/** /**
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
<link rel="import" href="actions.html"> <link rel="import" href="actions.html">
<link rel="import" href="browser_proxy.html"> <link rel="import" href="browser_proxy.html">
<link rel="import" href="main_view.html"> <link rel="import" href="main_view.html">
<link rel="import" href="router.html">
<link rel="import" href="store_client.html"> <link rel="import" href="store_client.html">
<link rel="import" href="store.html"> <link rel="import" href="store.html">
<link rel="import" href="../../../settings_shared_css.html"> <link rel="import" href="../../../settings_shared_css.html">
...@@ -19,7 +18,6 @@ ...@@ -19,7 +18,6 @@
<app-management-main-view search-term="[[searchTerm]]"> <app-management-main-view search-term="[[searchTerm]]">
</app-management-main-view> </app-management-main-view>
</div> </div>
<app-management-router></app-management-router>
</template> </template>
<script src="app_management_page.js"></script> <script src="app_management_page.js"></script>
</dom-module> </dom-module>
...@@ -8,6 +8,7 @@ Polymer({ ...@@ -8,6 +8,7 @@ Polymer({
behaviors: [ behaviors: [
app_management.StoreClient, app_management.StoreClient,
settings.RouteObserverBehavior,
], ],
properties: { properties: {
...@@ -15,22 +16,46 @@ Polymer({ ...@@ -15,22 +16,46 @@ Polymer({
* @type {App} * @type {App}
* @private * @private
*/ */
app_: Object, app_: {
type: Object,
observer: 'appChanged_',
}
}, },
attached: function() { attached: function() {
if (!this.app_) {
const appId = settings.getQueryParameters().get('id');
// TODO(crbug.com/999443): move this changePage call to router.js
this.dispatch(app_management.actions.changePage(PageType.DETAIL, appId));
}
this.watch('app_', state => app_management.util.getSelectedApp(state)); this.watch('app_', state => app_management.util.getSelectedApp(state));
this.watch('currentPage_', state => state.currentPage);
this.updateFromStore(); this.updateFromStore();
}, },
detached: function() {
this.dispatch(app_management.actions.updateSelectedAppId(null));
},
/**
* Updates selected app ID based on the URL query params.
*
* settings.RouteObserverBehavior
* @param {!settings.Route} currentRoute
* @protected
*/
currentRouteChanged: function(currentRoute) {
if (currentRoute !== settings.routes.APP_MANAGEMENT_DETAIL) {
return;
}
const appId = settings.getQueryParameters().get('id');
if (!this.getState().apps[appId]) {
// TODO(crbug.com/1010398): this call does not open the main page.
app_management.util.openMainPage();
return;
}
this.dispatch(app_management.actions.updateSelectedAppId(appId));
},
/** /**
* @param {App} app * @param {?App} app
* @return {?string} * @return {?string}
* @private * @private
*/ */
...@@ -51,4 +76,14 @@ Polymer({ ...@@ -51,4 +76,14 @@ Polymer({
assertNotReached(); assertNotReached();
} }
}, },
/**
* @param {?App} app
* @private
*/
appChanged_: function(app) {
if (app === null) {
app_management.util.openMainPage();
}
}
}); });
...@@ -74,74 +74,40 @@ cr.define('app_management', function() { ...@@ -74,74 +74,40 @@ cr.define('app_management', function() {
} }
}; };
const CurrentPageState = {}; const ArcSupported = {};
/**
* @param {AppMap} apps
* @param {Object} action
* @return {Page}
*/
CurrentPageState.changePage = function(apps, action) {
if (action.pageType === PageType.DETAIL && apps[action.id]) {
return {
pageType: PageType.DETAIL,
selectedAppId: action.id,
};
} else {
return {
pageType: PageType.MAIN,
selectedAppId: null,
};
}
};
/**
* @param {Page} currentPage
* @param {Object} action
* @return {Page}
*/
CurrentPageState.removeApp = function(currentPage, action) {
if (currentPage.pageType === PageType.DETAIL &&
currentPage.selectedAppId === action.id) {
return {
pageType: PageType.MAIN,
selectedAppId: null,
};
} else {
return currentPage;
}
};
/** /**
* @param {AppMap} apps * @param {boolean} arcSupported
* @param {Page} currentPage
* @param {Object} action * @param {Object} action
* @return {Page} * @return {boolean}
*/ */
CurrentPageState.updateCurrentPage = function(apps, currentPage, action) { ArcSupported.updateArcSupported = function(arcSupported, action) {
switch (action.name) { switch (action.name) {
case 'change-page': case 'update-arc-supported':
return CurrentPageState.changePage(apps, action); return action.value;
case 'remove-app':
return CurrentPageState.removeApp(currentPage, action);
default: default:
return currentPage; return arcSupported;
} }
}; };
const ArcSupported = {}; const SelectedAppId = {};
/** /**
* @param {boolean} arcSupported * @param {?string} selectedAppId
* @param {Object} action * @param {Object} action
* @return {boolean} * @return {?string}
*/ */
ArcSupported.updateArcSupported = function(arcSupported, action) { SelectedAppId.updateSelectedAppId = function(selectedAppId, action) {
switch (action.name) { switch (action.name) {
case 'update-arc-supported': case 'update-selected-app-id':
return action.value; return action.value;
case 'remove-app':
if (selectedAppId === action.id) {
return null;
}
return selectedAppId;
default: default:
return arcSupported; return selectedAppId;
} }
}; };
...@@ -155,16 +121,16 @@ cr.define('app_management', function() { ...@@ -155,16 +121,16 @@ cr.define('app_management', function() {
function reduceAction(state, action) { function reduceAction(state, action) {
return { return {
apps: AppState.updateApps(state.apps, action), apps: AppState.updateApps(state.apps, action),
currentPage: CurrentPageState.updateCurrentPage(
state.apps, state.currentPage, action),
arcSupported: ArcSupported.updateArcSupported(state.arcSupported, action), arcSupported: ArcSupported.updateArcSupported(state.arcSupported, action),
selectedAppId:
SelectedAppId.updateSelectedAppId(state.selectedAppId, action),
}; };
} }
return { return {
reduceAction: reduceAction, reduceAction: reduceAction,
AppState: AppState, AppState: AppState,
CurrentPageState: CurrentPageState,
ArcSupported: ArcSupported, ArcSupported: ArcSupported,
SelectedAppId: SelectedAppId,
}; };
}); });
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="actions.html">
<link rel="import" href="store_client.html">
<link rel="import" href="constants.html">
<dom-module id="app-management-router">
<template>
</template>
<script src="router.js"></script>
</dom-module>
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Polymer({
is: 'app-management-router',
behaviors: [
app_management.StoreClient,
],
//TODO (crbug.com/999443): Watch URL and update state.
properties: {
currentPage_: {
type: Object,
observer: 'onCurrentPageChanged_',
},
},
attached: function() {
this.watch('currentPage_', state => {
return state.currentPage;
});
this.updateFromStore();
},
onCurrentPageChanged_: function() {
const pageType = this.currentPage_.pageType;
const appId = this.currentPage_.selectedAppId;
switch(pageType) {
case PageType.DETAIL:
const params = new URLSearchParams;
params.append('id', appId);
settings.navigateTo(settings.routes.APP_MANAGEMENT_DETAIL, params);
return;
case PageType.MAIN:
settings.navigateTo(settings.routes.APP_MANAGEMENT);
return;
default:
assertNotReached();
}
}
});
...@@ -27,19 +27,11 @@ let Permission; ...@@ -27,19 +27,11 @@ let Permission;
*/ */
let AppMap; let AppMap;
/**
* @typedef {{
* pageType: PageType,
* selectedAppId: ?string,
* }}
*/
let Page;
/** /**
* @typedef {{ * @typedef {{
* apps: !AppMap, * apps: !AppMap,
* currentPage: !Page,
* arcSupported: boolean, * arcSupported: boolean,
* selectedAppId: ?string,
* }} * }}
*/ */
let AppManagementPageState; let AppManagementPageState;
...@@ -13,11 +13,8 @@ cr.define('app_management.util', function() { ...@@ -13,11 +13,8 @@ cr.define('app_management.util', function() {
function createEmptyState() { function createEmptyState() {
return { return {
apps: {}, apps: {},
currentPage: {
pageType: PageType.MAIN,
selectedAppId: null,
},
arcSupported: false, arcSupported: false,
selectedAppId: null,
}; };
} }
...@@ -144,7 +141,7 @@ cr.define('app_management.util', function() { ...@@ -144,7 +141,7 @@ cr.define('app_management.util', function() {
* @return {?App} * @return {?App}
*/ */
function getSelectedApp(state) { function getSelectedApp(state) {
const selectedAppId = state.currentPage.selectedAppId; const selectedAppId = state.selectedAppId;
return selectedAppId ? state.apps[selectedAppId] : null; return selectedAppId ? state.apps[selectedAppId] : null;
} }
...@@ -190,6 +187,24 @@ cr.define('app_management.util', function() { ...@@ -190,6 +187,24 @@ cr.define('app_management.util', function() {
} }
} }
/**
* Navigates to the App Detail page.
*
* @param {string} appId
*/
function openAppDetailPage(appId) {
const params = new URLSearchParams;
params.append('id', appId);
settings.navigateTo(settings.routes.APP_MANAGEMENT_DETAIL, params);
}
/**
* Navigates to the main App Management list page.
*/
function openMainPage() {
settings.navigateTo(settings.routes.APP_MANAGEMENT);
}
return { return {
addIfNeeded: addIfNeeded, addIfNeeded: addIfNeeded,
alphabeticalSort: alphabeticalSort, alphabeticalSort: alphabeticalSort,
...@@ -201,6 +216,8 @@ cr.define('app_management.util', function() { ...@@ -201,6 +216,8 @@ cr.define('app_management.util', function() {
getPermission: getPermission, getPermission: getPermission,
getPermissionValueBool: getPermissionValueBool, getPermissionValueBool: getPermissionValueBool,
getSelectedApp: getSelectedApp, getSelectedApp: getSelectedApp,
openAppDetailPage: openAppDetailPage,
openMainPage: openMainPage,
permissionTypeHandle: permissionTypeHandle, permissionTypeHandle: permissionTypeHandle,
removeIfNeeded: removeIfNeeded, removeIfNeeded: removeIfNeeded,
toggleOptionalBool: toggleOptionalBool, toggleOptionalBool: toggleOptionalBool,
......
...@@ -151,12 +151,6 @@ ...@@ -151,12 +151,6 @@
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CHROME_APP_PERMISSION_VIEW_HTML" <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CHROME_APP_PERMISSION_VIEW_HTML"
file="chromeos/os_apps_page/app_management_page/chrome_app_permission_view.html" file="chromeos/os_apps_page/app_management_page/chrome_app_permission_view.html"
type="chrome_html" /> type="chrome_html" />
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ROUTER_JS"
file="chromeos/os_apps_page/app_management_page/router.js"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ROUTER_HTML"
file="chromeos/os_apps_page/app_management_page/router.html"
type="chrome_html" />
<structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ICONS_HTML" <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ICONS_HTML"
file="chromeos/os_apps_page/app_management_page/icons.html" file="chromeos/os_apps_page/app_management_page/icons.html"
type="chrome_html" /> type="chrome_html" />
......
...@@ -48,7 +48,7 @@ suite('<app-management-arc-permission-view>', () => { ...@@ -48,7 +48,7 @@ suite('<app-management-arc-permission-view>', () => {
// Add an arc app, and make it the currently selected app. // Add an arc app, and make it the currently selected app.
const app = await fakeHandler.addApp(null, arcOptions); const app = await fakeHandler.addApp(null, arcOptions);
app_management.Store.getInstance().dispatch( app_management.Store.getInstance().dispatch(
app_management.actions.changePage(PageType.DETAIL, app.id)); app_management.actions.updateSelectedAppId(app.id));
arcPermissionView = arcPermissionView =
document.createElement('app-management-arc-permission-view'); document.createElement('app-management-arc-permission-view');
...@@ -57,7 +57,7 @@ suite('<app-management-arc-permission-view>', () => { ...@@ -57,7 +57,7 @@ suite('<app-management-arc-permission-view>', () => {
test('App is rendered correctly', () => { test('App is rendered correctly', () => {
assertEquals( assertEquals(
app_management.Store.getInstance().data.currentPage.selectedAppId, app_management.Store.getInstance().data.selectedAppId,
arcPermissionView.app_.id); arcPermissionView.app_.id);
}); });
......
...@@ -35,7 +35,7 @@ suite('<app-management-managed-apps>', () => { ...@@ -35,7 +35,7 @@ suite('<app-management-managed-apps>', () => {
const app = await fakeHandler.addApp(null, policyAppOptions); const app = await fakeHandler.addApp(null, policyAppOptions);
// Select created app. // Select created app.
app_management.Store.getInstance().dispatch( app_management.Store.getInstance().dispatch(
app_management.actions.changePage(PageType.DETAIL, app.id)); app_management.actions.updateSelectedAppId(app.id));
appDetailView = appDetailView =
document.createElement('app-management-pwa-permission-view'); document.createElement('app-management-pwa-permission-view');
replaceBody(appDetailView); replaceBody(appDetailView);
......
...@@ -20,8 +20,7 @@ suite('<app-management-pwa-permission-view>', function() { ...@@ -20,8 +20,7 @@ suite('<app-management-pwa-permission-view>', function() {
function getSelectedAppFromStore() { function getSelectedAppFromStore() {
const storeData = app_management.Store.getInstance().data; const storeData = app_management.Store.getInstance().data;
const selectedAppId = storeData.currentPage.selectedAppId; return storeData.apps[storeData.selectedAppId];
return storeData.apps[selectedAppId];
} }
setup(async function() { setup(async function() {
...@@ -31,7 +30,7 @@ suite('<app-management-pwa-permission-view>', function() { ...@@ -31,7 +30,7 @@ suite('<app-management-pwa-permission-view>', function() {
// Add an app, and make it the currently selected app. // Add an app, and make it the currently selected app.
const app = await fakeHandler.addApp(); const app = await fakeHandler.addApp();
app_management.Store.getInstance().dispatch( app_management.Store.getInstance().dispatch(
app_management.actions.changePage(PageType.DETAIL, app.id)); app_management.actions.updateSelectedAppId(app.id));
pwaPermissionView = pwaPermissionView =
document.createElement('app-management-pwa-permission-view'); document.createElement('app-management-pwa-permission-view');
...@@ -40,7 +39,7 @@ suite('<app-management-pwa-permission-view>', function() { ...@@ -40,7 +39,7 @@ suite('<app-management-pwa-permission-view>', function() {
test('App is rendered correctly', function() { test('App is rendered correctly', function() {
assertEquals( assertEquals(
app_management.Store.getInstance().data.currentPage.selectedAppId, app_management.Store.getInstance().data.selectedAppId,
pwaPermissionView.app_.id); pwaPermissionView.app_.id);
}); });
......
...@@ -57,7 +57,7 @@ suite('app state', function() { ...@@ -57,7 +57,7 @@ suite('app state', function() {
}); });
}); });
suite('current page state', function() { suite('selected app id', function() {
let state; let state;
setup(function() { setup(function() {
...@@ -67,65 +67,31 @@ suite('current page state', function() { ...@@ -67,65 +67,31 @@ suite('current page state', function() {
]); ]);
}); });
test( test('initial state has no selected app', function() {
'returns to main page if an app is removed while in its detail page', assertEquals(null, state.selectedAppId);
function() { });
state.currentPage.selectedAppId = '1';
state.currentPage.pageType = PageType.DETAIL;
let action = app_management.actions.removeApp('1');
state = app_management.reduceAction(state, action);
assertEquals(null, state.currentPage.selectedAppId);
assertEquals(PageType.MAIN, state.currentPage.pageType);
// Page doesn't change if a different app is removed.
state.apps['1'] = createApp('1');
state.currentPage.selectedAppId = '1';
state.currentPage.pageType = PageType.DETAIL;
action = app_management.actions.removeApp('2');
state = app_management.reduceAction(state, action);
assertEquals('1', state.currentPage.selectedAppId);
assertEquals(PageType.DETAIL, state.currentPage.pageType);
});
test('current page updates when changing to main page', function() {
// Returning to main page results in no selected app.
state.currentPage.selectedAppId = '1';
state.currentPage.pageType = PageType.DETAIL;
let action = app_management.actions.changePage(PageType.MAIN); test('updates selected app id', function() {
let action = app_management.actions.updateSelectedAppId('1');
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals('1', state.selectedAppId);
assertEquals(null, state.currentPage.selectedAppId); action = app_management.actions.updateSelectedAppId('2');
assertEquals(PageType.MAIN, state.currentPage.pageType);
// Id is disregarded when changing to main page.
action = app_management.actions.changePage(PageType.MAIN, '1');
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals('2', state.selectedAppId);
assertEquals(null, state.currentPage.selectedAppId); action = app_management.actions.updateSelectedAppId(null);
assertEquals(PageType.MAIN, state.currentPage.pageType); state = app_management.reduceAction(state, action);
assertEquals(null, state.selectedAppId);
}); });
test('current page updates when changing to app detail page', function() { test('removing an app resets selected app id', function() {
// State updates when a valid app detail page is selected. let action = app_management.actions.updateSelectedAppId('1');
let action = app_management.actions.changePage(PageType.DETAIL, '2');
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals('1', state.selectedAppId);
assertEquals('2', state.currentPage.selectedAppId); action = app_management.actions.removeApp('1');
assertEquals(PageType.DETAIL, state.currentPage.pageType);
// State returns to main page if invalid app id is given.
state.currentPage.selectedAppId = '2';
state.currentPage.pageType = PageType.DETAIL;
action = app_management.actions.changePage(PageType.DETAIL, '3');
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals(null, state.selectedAppId);
assertEquals(null, state.currentPage.selectedAppId);
assertEquals(PageType.MAIN, state.currentPage.pageType);
}); });
}); });
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
suite('<app-management-router>', () => {
let store;
let router;
let fakeHandler;
setup(async () => {
fakeHandler = setupFakeHandler();
store = replaceStore();
await fakeHandler.addApp('1');
router = document.createElement('app-management-router');
replaceBody(router);
});
test('Search updates from route', async () => {
await navigateTo('/?q=beep');
const expected = app_management.actions.setSearchTerm('beep');
assertDeepEquals(expected, store.lastAction);
});
test('Selected app updates from route', async () => {
await navigateTo('/detail?id=1');
const expected = app_management.actions.changePage(PageType.DETAIL, '1');
assertDeepEquals(expected, store.lastAction);
});
test('Notifications view appears from route', async () => {
await navigateTo('/notifications');
const expected = app_management.actions.changePage(PageType.NOTIFICATIONS);
assertDeepEquals(expected, store.lastAction);
});
test('Route updates from state change', async () => {
// The application needs an initial url to start with.
await navigateTo('/');
store.data.currentPage = {
pageType: PageType.DETAIL,
selectedAppId: '1',
};
store.notifyObservers();
await test_util.flushTasks();
expectEquals('/detail?id=1', getCurrentUrlSuffix());
// Returning main page clears the route.
store.data.currentPage = {
pageType: PageType.MAIN,
selectedAppId: null,
};
store.notifyObservers();
await test_util.flushTasks();
expectEquals('/', getCurrentUrlSuffix());
store.data.currentPage = {
pageType: PageType.NOTIFICATIONS,
selectedAppId: null,
};
store.notifyObservers();
await test_util.flushTasks();
expectEquals('/notifications', getCurrentUrlSuffix());
});
test('Route updates from home to search', async () => {
await navigateTo('/');
store.data.search = {term: 'bloop'};
store.notifyObservers();
await test_util.flushTasks();
expectEquals('/?q=bloop', getCurrentUrlSuffix());
});
test('Route updates from detail to search', async () => {
await navigateTo('/detail?id=1');
store.data.search = {term: 'bloop'};
store.notifyObservers();
await test_util.flushTasks();
expectEquals('/detail?id=1&q=bloop', getCurrentUrlSuffix());
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment