diff --git a/public/app/containers/ContainerProps.ts b/public/app/containers/ContainerProps.ts index ce09b992f80..84c395413b6 100644 --- a/public/app/containers/ContainerProps.ts +++ b/public/app/containers/ContainerProps.ts @@ -1,13 +1,11 @@ import { NavStore } from './../stores/NavStore/NavStore'; import { PermissionsStore } from './../stores/PermissionsStore/PermissionsStore'; import { ViewStore } from './../stores/ViewStore/ViewStore'; -import { FolderStore } from './../stores/FolderStore/FolderStore'; interface ContainerProps { nav: typeof NavStore.Type; permissions: typeof PermissionsStore.Type; view: typeof ViewStore.Type; - folder: typeof FolderStore.Type; backendSrv: any; } diff --git a/public/app/containers/ManageDashboards/FolderPermissions.tsx b/public/app/features/manage-dashboards/FolderPermissions.tsx similarity index 65% rename from public/app/containers/ManageDashboards/FolderPermissions.tsx rename to public/app/features/manage-dashboards/FolderPermissions.tsx index 072908d2b8e..00b229801f3 100644 --- a/public/app/containers/ManageDashboards/FolderPermissions.tsx +++ b/public/app/features/manage-dashboards/FolderPermissions.tsx @@ -2,24 +2,34 @@ import React, { Component } from 'react'; import { hot } from 'react-hot-loader'; import { inject, observer } from 'mobx-react'; import { toJS } from 'mobx'; -import ContainerProps from 'app/containers/ContainerProps'; +import { connect } from 'react-redux'; import PageHeader from 'app/core/components/PageHeader/PageHeader'; import Permissions from 'app/core/components/Permissions/Permissions'; import Tooltip from 'app/core/components/Tooltip/Tooltip'; import PermissionsInfo from 'app/core/components/Permissions/PermissionsInfo'; import AddPermissions from 'app/core/components/Permissions/AddPermissions'; import SlideDown from 'app/core/components/Animations/SlideDown'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { NavModel, StoreState, FolderState } from 'app/types'; +import { getFolderByUid, setFolderTitle, saveFolder, deleteFolder } from './state/actions'; -@inject('nav', 'folder', 'view', 'permissions') +export interface Props { + navModel: NavModel; + getFolderByUid: typeof getFolderByUid; + folderUid: string; + folder: FolderState; +} + +@inject('permissions') @observer -export class FolderPermissions extends Component { +export class FolderPermissions extends Component { constructor(props) { super(props); this.handleAddPermission = this.handleAddPermission.bind(this); } componentDidMount() { - this.loadStore(); + this.props.getFolderByUid(this.props.folderUid); } componentWillUnmount() { @@ -27,31 +37,23 @@ export class FolderPermissions extends Component { permissions.hideAddPermissions(); } - loadStore() { - const { nav, folder, view } = this.props; - return folder.load(view.routeParams.get('uid') as string).then(res => { - view.updatePathAndQuery(`${res.url}/permissions`, {}, {}); - return nav.initFolderNav(toJS(folder.folder), 'manage-folder-permissions'); - }); - } - handleAddPermission() { const { permissions } = this.props; permissions.toggleAddPermissions(); } render() { - const { nav, folder, permissions, backendSrv } = this.props; + const { navModel, permissions, backendSrv, folder } = this.props; - if (!folder.folder || !nav.main) { + if (folder.id === 0) { return

Loading

; } - const dashboardId = folder.folder.id; + const dashboardId = folder.id; return (
- +

Folder Permissions

@@ -77,4 +79,17 @@ export class FolderPermissions extends Component { } } -export default hot(module)(FolderPermissions); +const mapStateToProps = (state: StoreState) => { + const uid = state.location.routeParams.uid; + return { + navModel: getNavModel(state.navIndex, `folder-permissions-${uid}`), + folderUid: uid, + folder: state.folder, + }; +}; + +const mapDispatchToProps = { + getFolderByUid, +}; + +export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(FolderPermissions)); diff --git a/public/app/features/manage-dashboards/FolderSettingsPage.test.tsx b/public/app/features/manage-dashboards/FolderSettingsPage.test.tsx index bed3d569bcc..defec5e6a57 100644 --- a/public/app/features/manage-dashboards/FolderSettingsPage.test.tsx +++ b/public/app/features/manage-dashboards/FolderSettingsPage.test.tsx @@ -1,84 +1,54 @@ import React from 'react'; -import { FolderSettings } from './FolderSettings'; -import { RootStore } from 'app/stores/RootStore/RootStore'; -import { backendSrv } from 'test/mocks/common'; +import { FolderSettingsPage, Props } from './FolderSettingsPage'; +import { NavModel, FolderState } from '../../types'; import { shallow } from 'enzyme'; -describe('FolderSettings', () => { - let wrapper; - let page; +const setup = (propOverrides?: object) => { + const props: Props = { + navModel: {} as NavModel, + folderUid: '1234', + folder: { + id: 0, + uid: '1234', + title: 'loading', + canSave: true, + hasChanged: false, + version: 1, + }, + getFolderByUid: jest.fn(), + setFolderTitle: jest.fn(), + saveFolder: jest.fn(), + deleteFolder: jest.fn(), + }; - beforeAll(() => { - backendSrv.getFolderByUid.mockReturnValue( - Promise.resolve({ + Object.assign(props, propOverrides); + + const wrapper = shallow(); + const instance = wrapper.instance() as FolderSettingsPage; + + return { + wrapper, + instance, + }; +}; + +describe('Render', () => { + it('should render component', () => { + const { wrapper } = setup(); + expect(wrapper).toMatchSnapshot(); + }); + + it('should enable save button', () => { + const { wrapper } = setup({ + folder: { id: 1, - uid: 'uid', - title: 'Folder Name', - url: '/dashboards/f/uid/folder-name', + uid: '1234', + title: 'loading', canSave: true, + hasChanged: true, version: 1, - }) - ); - - const store = RootStore.create( - { - view: { - path: 'asd', - query: {}, - routeParams: { - uid: 'uid-str', - }, - }, }, - { - backendSrv: backendSrv, - } - ); - - wrapper = shallow(); - page = wrapper.dive(); - return page - .instance() - .loadStore() - .then(() => { - page.update(); - }); - }); - - it('should set the title input field', () => { - const titleInput = page.find('.gf-form-input'); - expect(titleInput).toHaveLength(1); - expect(titleInput.prop('value')).toBe('Folder Name'); - }); - - it('should update title and enable save button when changed', () => { - const titleInput = page.find('.gf-form-input'); - const disabledSubmitButton = page.find('button[type="submit"]'); - expect(disabledSubmitButton.prop('disabled')).toBe(true); - - titleInput.simulate('change', { target: { value: 'New Title' } }); - - const updatedTitleInput = page.find('.gf-form-input'); - expect(updatedTitleInput.prop('value')).toBe('New Title'); - const enabledSubmitButton = page.find('button[type="submit"]'); - expect(enabledSubmitButton.prop('disabled')).toBe(false); - }); - - it('should disable save button if title is changed back to old title', () => { - const titleInput = page.find('.gf-form-input'); - - titleInput.simulate('change', { target: { value: 'Folder Name' } }); - - const enabledSubmitButton = page.find('button[type="submit"]'); - expect(enabledSubmitButton.prop('disabled')).toBe(true); - }); - - it('should disable save button if title is changed to empty string', () => { - const titleInput = page.find('.gf-form-input'); - - titleInput.simulate('change', { target: { value: '' } }); - - const enabledSubmitButton = page.find('button[type="submit"]'); - expect(enabledSubmitButton.prop('disabled')).toBe(true); + }); + expect(wrapper).toMatchSnapshot(); }); }); diff --git a/public/app/features/manage-dashboards/__snapshots__/FolderSettingsPage.test.tsx.snap b/public/app/features/manage-dashboards/__snapshots__/FolderSettingsPage.test.tsx.snap new file mode 100644 index 00000000000..2de0c193d27 --- /dev/null +++ b/public/app/features/manage-dashboards/__snapshots__/FolderSettingsPage.test.tsx.snap @@ -0,0 +1,131 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Render should enable save button 1`] = ` +
+ +
+

+ Folder Settings +

+
+
+
+ + +
+
+ + +
+ +
+
+
+`; + +exports[`Render should render component 1`] = ` +
+ +
+

+ Folder Settings +

+
+
+
+ + +
+
+ + +
+ +
+
+
+`; diff --git a/public/app/features/manage-dashboards/state/reducers.ts b/public/app/features/manage-dashboards/state/reducers.ts index ada5b1812ad..41ae10d19e5 100644 --- a/public/app/features/manage-dashboards/state/reducers.ts +++ b/public/app/features/manage-dashboards/state/reducers.ts @@ -2,8 +2,8 @@ import { FolderState } from 'app/types'; import { Action, ActionTypes } from './actions'; export const inititalState: FolderState = { + id: 0, uid: 'loading', - id: -1, title: 'loading', url: '', canSave: false, @@ -22,7 +22,7 @@ export const folderReducer = (state = inititalState, action: Action): FolderStat return { ...state, title: action.payload, - hasChanged: true, + hasChanged: action.payload.trim().length > 0, }; } return state; diff --git a/public/app/routes/routes.ts b/public/app/routes/routes.ts index 93d83a3b7db..45e72e68c38 100644 --- a/public/app/routes/routes.ts +++ b/public/app/routes/routes.ts @@ -3,10 +3,10 @@ import './ReactContainer'; import ServerStats from 'app/features/admin/ServerStats'; import AlertRuleList from 'app/features/alerting/AlertRuleList'; -import FolderPermissions from 'app/containers/ManageDashboards/FolderPermissions'; import TeamPages from 'app/features/teams/TeamPages'; import TeamList from 'app/features/teams/TeamList'; import FolderSettingsPage from 'app/features/manage-dashboards/FolderSettingsPage'; +import FolderPermissions from 'app/features/manage-dashboards/FolderPermissions'; /** @ngInject */ export function setupAngularRoutes($routeProvider, $locationProvider) { diff --git a/public/app/stores/RootStore/RootStore.ts b/public/app/stores/RootStore/RootStore.ts index 37c13f48c61..68125fd1f4c 100644 --- a/public/app/stores/RootStore/RootStore.ts +++ b/public/app/stores/RootStore/RootStore.ts @@ -1,7 +1,6 @@ import { types } from 'mobx-state-tree'; import { NavStore } from './../NavStore/NavStore'; import { ViewStore } from './../ViewStore/ViewStore'; -import { FolderStore } from './../FolderStore/FolderStore'; import { PermissionsStore } from './../PermissionsStore/PermissionsStore'; export const RootStore = types.model({ @@ -15,7 +14,6 @@ export const RootStore = types.model({ query: {}, routeParams: {}, }), - folder: types.optional(FolderStore, {}), }); type RootStoreType = typeof RootStore.Type; diff --git a/public/app/types/dashboard.ts b/public/app/types/folder.ts similarity index 100% rename from public/app/types/dashboard.ts rename to public/app/types/folder.ts diff --git a/public/app/types/index.ts b/public/app/types/index.ts index b1096c4827c..52d1ba592c5 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -2,7 +2,7 @@ import { Team, TeamsState, TeamState, TeamGroup, TeamMember } from './teams'; import { AlertRuleDTO, AlertRule, AlertRulesState } from './alerting'; import { LocationState, LocationUpdate, UrlQueryMap, UrlQueryValue } from './location'; import { NavModel, NavModelItem, NavIndex } from './navModel'; -import { FolderDTO, FolderState } from './dashboard'; +import { FolderDTO, FolderState } from './folder'; export { Team,