wip: folder settings page to redux progress
This commit is contained in:
@@ -9,8 +9,8 @@ export const initialState: LocationState = {
|
|||||||
routeParams: {},
|
routeParams: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderUrl(path: string, query: UrlQueryMap): string {
|
function renderUrl(path: string, query: UrlQueryMap | undefined): string {
|
||||||
if (Object.keys(query).length > 0) {
|
if (query && Object.keys(query).length > 0) {
|
||||||
path += '?' + toUrlParams(query);
|
path += '?' + toUrlParams(query);
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
|
|||||||
@@ -252,16 +252,6 @@ export class BackendSrv {
|
|||||||
return this.post('/api/folders', payload);
|
return this.post('/api/folders', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFolder(folder, options) {
|
|
||||||
options = options || {};
|
|
||||||
|
|
||||||
return this.put(`/api/folders/${folder.uid}`, {
|
|
||||||
title: folder.title,
|
|
||||||
version: folder.version,
|
|
||||||
overwrite: options.overwrite === true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteFolder(uid: string, showSuccessAlert) {
|
deleteFolder(uid: string, showSuccessAlert) {
|
||||||
return this.request({ method: 'DELETE', url: `/api/folders/${uid}`, showSuccessAlert: showSuccessAlert === true });
|
return this.request({ method: 'DELETE', url: `/api/folders/${uid}`, showSuccessAlert: showSuccessAlert === true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,9 @@ import './dashlinks/module';
|
|||||||
|
|
||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
import { FolderDashboardsCtrl } from './folder_dashboards_ctrl';
|
import { FolderDashboardsCtrl } from './folder_dashboards_ctrl';
|
||||||
import { FolderSettingsCtrl } from './folder_settings_ctrl';
|
|
||||||
import { DashboardImportCtrl } from './dashboard_import_ctrl';
|
import { DashboardImportCtrl } from './dashboard_import_ctrl';
|
||||||
import { CreateFolderCtrl } from './create_folder_ctrl';
|
import { CreateFolderCtrl } from './create_folder_ctrl';
|
||||||
|
|
||||||
coreModule.controller('FolderDashboardsCtrl', FolderDashboardsCtrl);
|
coreModule.controller('FolderDashboardsCtrl', FolderDashboardsCtrl);
|
||||||
coreModule.controller('FolderSettingsCtrl', FolderSettingsCtrl);
|
|
||||||
coreModule.controller('DashboardImportCtrl', DashboardImportCtrl);
|
coreModule.controller('DashboardImportCtrl', DashboardImportCtrl);
|
||||||
coreModule.controller('CreateFolderCtrl', CreateFolderCtrl);
|
coreModule.controller('CreateFolderCtrl', CreateFolderCtrl);
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
import { FolderPageLoader } from './folder_page_loader';
|
|
||||||
import appEvents from 'app/core/app_events';
|
|
||||||
|
|
||||||
export class FolderSettingsCtrl {
|
|
||||||
folderPageLoader: FolderPageLoader;
|
|
||||||
navModel: any;
|
|
||||||
folderId: number;
|
|
||||||
uid: string;
|
|
||||||
canSave = false;
|
|
||||||
folder: any;
|
|
||||||
title: string;
|
|
||||||
hasChanged: boolean;
|
|
||||||
|
|
||||||
/** @ngInject */
|
|
||||||
constructor(private backendSrv, navModelSrv, private $routeParams, private $location) {
|
|
||||||
if (this.$routeParams.uid) {
|
|
||||||
this.uid = $routeParams.uid;
|
|
||||||
|
|
||||||
this.folderPageLoader = new FolderPageLoader(this.backendSrv);
|
|
||||||
this.folderPageLoader.load(this, this.uid, 'manage-folder-settings').then(folder => {
|
|
||||||
if ($location.path() !== folder.meta.url) {
|
|
||||||
$location.path(`${folder.meta.url}/settings`).replace();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.folder = folder;
|
|
||||||
this.canSave = this.folder.canSave;
|
|
||||||
this.title = this.folder.title;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save() {
|
|
||||||
this.titleChanged();
|
|
||||||
|
|
||||||
if (!this.hasChanged) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.folder.title = this.title.trim();
|
|
||||||
|
|
||||||
return this.backendSrv
|
|
||||||
.updateFolder(this.folder)
|
|
||||||
.then(result => {
|
|
||||||
if (result.url !== this.$location.path()) {
|
|
||||||
this.$location.url(result.url + '/settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
appEvents.emit('dashboard-saved');
|
|
||||||
appEvents.emit('alert-success', ['Folder saved']);
|
|
||||||
})
|
|
||||||
.catch(this.handleSaveFolderError);
|
|
||||||
}
|
|
||||||
|
|
||||||
titleChanged() {
|
|
||||||
this.hasChanged = this.folder.title.toLowerCase() !== this.title.trim().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(evt) {
|
|
||||||
if (evt) {
|
|
||||||
evt.stopPropagation();
|
|
||||||
evt.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
appEvents.emit('confirm-modal', {
|
|
||||||
title: 'Delete',
|
|
||||||
text: `Do you want to delete this folder and all its dashboards?`,
|
|
||||||
icon: 'fa-trash',
|
|
||||||
yesText: 'Delete',
|
|
||||||
onConfirm: () => {
|
|
||||||
return this.backendSrv.deleteFolder(this.uid).then(() => {
|
|
||||||
appEvents.emit('alert-success', ['Folder Deleted', `${this.folder.title} has been deleted`]);
|
|
||||||
this.$location.url('dashboards');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSaveFolderError(err) {
|
|
||||||
if (err.data && err.data.status === 'version-mismatch') {
|
|
||||||
err.isHandled = true;
|
|
||||||
|
|
||||||
appEvents.emit('confirm-modal', {
|
|
||||||
title: 'Conflict',
|
|
||||||
text: 'Someone else has updated this folder.',
|
|
||||||
text2: 'Would you still like to save this folder?',
|
|
||||||
yesText: 'Save & Overwrite',
|
|
||||||
icon: 'fa-warning',
|
|
||||||
onConfirm: () => {
|
|
||||||
this.backendSrv.updateFolder(this.folder, { overwrite: true });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,121 +4,53 @@ import { connect } from 'react-redux';
|
|||||||
import PageHeader from 'app/core/components/PageHeader/PageHeader';
|
import PageHeader from 'app/core/components/PageHeader/PageHeader';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
import { getNavModel } from 'app/core/selectors/navModel';
|
import { getNavModel } from 'app/core/selectors/navModel';
|
||||||
import { NavModel, StoreState } from 'app/types';
|
import { NavModel, StoreState, FolderState } from 'app/types';
|
||||||
import { getFolderByUid } from './state/actions';
|
import { getFolderByUid, setFolderTitle, saveFolder, deleteFolder } from './state/actions';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
navModel: NavModel;
|
navModel: NavModel;
|
||||||
folderUid: string;
|
folderUid: string;
|
||||||
|
folder: FolderState;
|
||||||
getFolderByUid: typeof getFolderByUid;
|
getFolderByUid: typeof getFolderByUid;
|
||||||
|
setFolderTitle: typeof setFolderTitle;
|
||||||
|
saveFolder: typeof saveFolder;
|
||||||
|
deleteFolder: typeof deleteFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FolderSettingsPage extends PureComponent<Props> {
|
export class FolderSettingsPage extends PureComponent<Props> {
|
||||||
// formSnapshot: any;
|
|
||||||
//
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.getFolderByUid(this.props.folderUid);
|
this.props.getFolderByUid(this.props.folderUid);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// loadStore() {
|
|
||||||
// const { nav, folder, view } = this.props;
|
|
||||||
//
|
|
||||||
// return folder.load(view.routeParams.get('uid') as string).then(res => {
|
|
||||||
// this.formSnapshot = getSnapshot(folder);
|
|
||||||
// view.updatePathAndQuery(`${res.url}/settings`, {}, {});
|
|
||||||
//
|
|
||||||
// return nav.initFolderNav(toJS(folder.folder), 'manage-folder-settings');
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// onTitleChange(evt) {
|
onTitleChange = evt => {
|
||||||
// this.props.folder.setTitle(this.getFormSnapshot().folder.title, evt.target.value);
|
this.props.setFolderTitle(evt.target.value);
|
||||||
// }
|
};
|
||||||
//
|
|
||||||
// getFormSnapshot() {
|
onSave = async evt => {
|
||||||
// if (!this.formSnapshot) {
|
evt.preventDefault();
|
||||||
// this.formSnapshot = getSnapshot(this.props.folder);
|
evt.stopPropagation();
|
||||||
// }
|
|
||||||
//
|
await this.props.saveFolder(this.props.folder);
|
||||||
// return this.formSnapshot;
|
appEvents.emit('alert-success', ['Folder saved']);
|
||||||
// }
|
};
|
||||||
//
|
|
||||||
// save(evt) {
|
onDelete = evt => {
|
||||||
// if (evt) {
|
evt.stopPropagation();
|
||||||
// evt.stopPropagation();
|
evt.preventDefault();
|
||||||
// evt.preventDefault();
|
|
||||||
// }
|
appEvents.emit('confirm-modal', {
|
||||||
//
|
title: 'Delete',
|
||||||
// const { nav, folder, view } = this.props;
|
text: `Do you want to delete this folder and all its dashboards?`,
|
||||||
//
|
icon: 'fa-trash',
|
||||||
// folder
|
yesText: 'Delete',
|
||||||
// .saveFolder({ overwrite: false })
|
onConfirm: () => {
|
||||||
// .then(newUrl => {
|
this.props.deleteFolder(this.props.folder.uid);
|
||||||
// view.updatePathAndQuery(newUrl, {}, {});
|
},
|
||||||
//
|
});
|
||||||
// appEvents.emit('dashboard-saved');
|
};
|
||||||
// appEvents.emit('alert-success', ['Folder saved']);
|
|
||||||
// })
|
|
||||||
// .then(() => {
|
|
||||||
// return nav.initFolderNav(toJS(folder.folder), 'manage-folder-settings');
|
|
||||||
// })
|
|
||||||
// .catch(this.handleSaveFolderError.bind(this));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// delete(evt) {
|
|
||||||
// if (evt) {
|
|
||||||
// evt.stopPropagation();
|
|
||||||
// evt.preventDefault();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const { folder, view } = this.props;
|
|
||||||
// const title = folder.folder.title;
|
|
||||||
//
|
|
||||||
// appEvents.emit('confirm-modal', {
|
|
||||||
// title: 'Delete',
|
|
||||||
// text: `Do you want to delete this folder and all its dashboards?`,
|
|
||||||
// icon: 'fa-trash',
|
|
||||||
// yesText: 'Delete',
|
|
||||||
// onConfirm: () => {
|
|
||||||
// return folder.deleteFolder().then(() => {
|
|
||||||
// appEvents.emit('alert-success', ['Folder Deleted', `${title} has been deleted`]);
|
|
||||||
// view.updatePathAndQuery('dashboards', '', '');
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// handleSaveFolderError(err) {
|
|
||||||
// if (err.data && err.data.status === 'version-mismatch') {
|
|
||||||
// err.isHandled = true;
|
|
||||||
//
|
|
||||||
// const { nav, folder, view } = this.props;
|
|
||||||
//
|
|
||||||
// appEvents.emit('confirm-modal', {
|
|
||||||
// title: 'Conflict',
|
|
||||||
// text: 'Someone else has updated this folder.',
|
|
||||||
// text2: 'Would you still like to save this folder?',
|
|
||||||
// yesText: 'Save & Overwrite',
|
|
||||||
// icon: 'fa-warning',
|
|
||||||
// onConfirm: () => {
|
|
||||||
// folder
|
|
||||||
// .saveFolder({ overwrite: true })
|
|
||||||
// .then(newUrl => {
|
|
||||||
// view.updatePathAndQuery(newUrl, {}, {});
|
|
||||||
//
|
|
||||||
// appEvents.emit('dashboard-saved');
|
|
||||||
// appEvents.emit('alert-success', ['Folder saved']);
|
|
||||||
// })
|
|
||||||
// .then(() => {
|
|
||||||
// return nav.initFolderNav(toJS(folder.folder), 'manage-folder-settings');
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { navModel } = this.props;
|
const { navModel, folder } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -127,25 +59,21 @@ export class FolderSettingsPage extends PureComponent<Props> {
|
|||||||
<h2 className="page-sub-heading">Folder Settings</h2>
|
<h2 className="page-sub-heading">Folder Settings</h2>
|
||||||
|
|
||||||
<div className="section gf-form-group">
|
<div className="section gf-form-group">
|
||||||
<form name="folderSettingsForm" onSubmit={this.save.bind(this)}>
|
<form name="folderSettingsForm" onSubmit={this.onSave}>
|
||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
<label className="gf-form-label width-7">Name</label>
|
<label className="gf-form-label width-7">Name</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="gf-form-input width-30"
|
className="gf-form-input width-30"
|
||||||
value={folder.folder.title}
|
value={folder.title}
|
||||||
onChange={this.onTitleChange.bind(this)}
|
onChange={this.onTitleChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="gf-form-button-row">
|
<div className="gf-form-button-row">
|
||||||
<button
|
<button type="submit" className="btn btn-success" disabled={!folder.canSave || !folder.hasChanged}>
|
||||||
type="submit"
|
|
||||||
className="btn btn-success"
|
|
||||||
disabled={!folder.folder.canSave || !folder.folder.hasChanged}
|
|
||||||
>
|
|
||||||
<i className="fa fa-save" /> Save
|
<i className="fa fa-save" /> Save
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-danger" onClick={this.delete.bind(this)} disabled={!folder.folder.canSave}>
|
<button className="btn btn-danger" onClick={this.onDelete} disabled={!folder.canSave}>
|
||||||
<i className="fa fa-trash" /> Delete
|
<i className="fa fa-trash" /> Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -159,7 +87,6 @@ export class FolderSettingsPage extends PureComponent<Props> {
|
|||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => {
|
const mapStateToProps = (state: StoreState) => {
|
||||||
const uid = state.location.routeParams.uid;
|
const uid = state.location.routeParams.uid;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
navModel: getNavModel(state.navIndex, `folder-settings-${uid}`),
|
navModel: getNavModel(state.navIndex, `folder-settings-${uid}`),
|
||||||
folderUid: uid,
|
folderUid: uid,
|
||||||
@@ -169,6 +96,9 @@ const mapStateToProps = (state: StoreState) => {
|
|||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
getFolderByUid,
|
getFolderByUid,
|
||||||
|
saveFolder,
|
||||||
|
setFolderTitle,
|
||||||
|
deleteFolder,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(FolderSettingsPage));
|
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(FolderSettingsPage));
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { StoreState } from 'app/types';
|
import { StoreState } from 'app/types';
|
||||||
import { ThunkAction } from 'redux-thunk';
|
import { ThunkAction } from 'redux-thunk';
|
||||||
import { FolderDTO, NavModelItem } from 'app/types';
|
import { FolderDTO, FolderState, NavModelItem } from 'app/types';
|
||||||
import { updateNavIndex, UpdateNavIndexAction } from 'app/core/actions';
|
import { updateNavIndex, updateLocation } from 'app/core/actions';
|
||||||
|
|
||||||
export enum ActionTypes {
|
export enum ActionTypes {
|
||||||
LoadFolder = 'LOAD_FOLDER',
|
LoadFolder = 'LOAD_FOLDER',
|
||||||
@@ -32,7 +32,7 @@ export const setFolderTitle = (newTitle: string): SetFolderTitleAction => ({
|
|||||||
|
|
||||||
export type Action = LoadFolderAction | SetFolderTitleAction;
|
export type Action = LoadFolderAction | SetFolderTitleAction;
|
||||||
|
|
||||||
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action | UpdateNavIndexAction>;
|
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, any>;
|
||||||
|
|
||||||
function buildNavModel(folder: FolderDTO): NavModelItem {
|
function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||||
return {
|
return {
|
||||||
@@ -67,6 +67,7 @@ function buildNavModel(folder: FolderDTO): NavModelItem {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFolderByUid(uid: string): ThunkResult<void> {
|
export function getFolderByUid(uid: string): ThunkResult<void> {
|
||||||
return async dispatch => {
|
return async dispatch => {
|
||||||
const folder = await getBackendSrv().getFolderByUid(uid);
|
const folder = await getBackendSrv().getFolderByUid(uid);
|
||||||
@@ -74,3 +75,20 @@ export function getFolderByUid(uid: string): ThunkResult<void> {
|
|||||||
dispatch(updateNavIndex(buildNavModel(folder)));
|
dispatch(updateNavIndex(buildNavModel(folder)));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function saveFolder(folder: FolderState): ThunkResult<void> {
|
||||||
|
return async dispatch => {
|
||||||
|
const res = await getBackendSrv().put(`/api/folders/${folder.uid}`, {
|
||||||
|
title: folder.title,
|
||||||
|
version: folder.version,
|
||||||
|
});
|
||||||
|
dispatch(updateLocation({ path: `${res.url}/settings` }));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteFolder(uid: string): ThunkResult<void> {
|
||||||
|
return async dispatch => {
|
||||||
|
await getBackendSrv().deleteFolder(uid, true);
|
||||||
|
dispatch(updateLocation({ path: `dashboards` }));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,14 @@ export const folderReducer = (state = inititalState, action: Action): FolderStat
|
|||||||
case ActionTypes.LoadFolder:
|
case ActionTypes.LoadFolder:
|
||||||
return {
|
return {
|
||||||
...action.payload,
|
...action.payload,
|
||||||
canSave: false,
|
|
||||||
hasChanged: false,
|
hasChanged: false,
|
||||||
};
|
};
|
||||||
|
case ActionTypes.SetFolderTitle:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
title: action.payload,
|
||||||
|
hasChanged: true,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
import { types, getEnv, flow } from 'mobx-state-tree';
|
|
||||||
|
|
||||||
export const Folder = types.model('Folder', {
|
|
||||||
id: types.identifier(types.number),
|
|
||||||
uid: types.string,
|
|
||||||
title: types.string,
|
|
||||||
url: types.string,
|
|
||||||
canSave: types.boolean,
|
|
||||||
hasChanged: types.boolean,
|
|
||||||
version: types.number,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const FolderStore = types
|
|
||||||
.model('FolderStore', {
|
|
||||||
folder: types.maybe(Folder),
|
|
||||||
})
|
|
||||||
.actions(self => ({
|
|
||||||
load: flow(function* load(uid: string) {
|
|
||||||
// clear folder state
|
|
||||||
if (self.folder && self.folder.uid !== uid) {
|
|
||||||
self.folder = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const backendSrv = getEnv(self).backendSrv;
|
|
||||||
const res = yield backendSrv.getFolderByUid(uid);
|
|
||||||
self.folder = Folder.create({
|
|
||||||
id: res.id,
|
|
||||||
uid: res.uid,
|
|
||||||
title: res.title,
|
|
||||||
url: res.url,
|
|
||||||
canSave: res.canSave,
|
|
||||||
hasChanged: false,
|
|
||||||
version: res.version,
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}),
|
|
||||||
|
|
||||||
setTitle: (originalTitle: string, title: string) => {
|
|
||||||
self.folder.title = title;
|
|
||||||
self.folder.hasChanged = originalTitle.toLowerCase() !== title.trim().toLowerCase() && title.trim().length > 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
saveFolder: flow(function* saveFolder(options: any) {
|
|
||||||
const backendSrv = getEnv(self).backendSrv;
|
|
||||||
self.folder.title = self.folder.title.trim();
|
|
||||||
|
|
||||||
const res = yield backendSrv.updateFolder(self.folder, options);
|
|
||||||
self.folder.url = res.url;
|
|
||||||
self.folder.version = res.version;
|
|
||||||
|
|
||||||
return `${self.folder.url}/settings`;
|
|
||||||
}),
|
|
||||||
|
|
||||||
deleteFolder: flow(function* deleteFolder() {
|
|
||||||
const backendSrv = getEnv(self).backendSrv;
|
|
||||||
|
|
||||||
return backendSrv.deleteFolder(self.folder.uid);
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
@@ -4,6 +4,7 @@ export interface FolderDTO {
|
|||||||
title: string;
|
title: string;
|
||||||
url: string;
|
url: string;
|
||||||
version: number;
|
version: number;
|
||||||
|
canSave: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FolderState {
|
export interface FolderState {
|
||||||
|
|||||||
@@ -30,4 +30,5 @@ export interface StoreState {
|
|||||||
alertRules: AlertRulesState;
|
alertRules: AlertRulesState;
|
||||||
teams: TeamsState;
|
teams: TeamsState;
|
||||||
team: TeamState;
|
team: TeamState;
|
||||||
|
folder: FolderState;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user