refactor(templates): normalize Templates (#16642)
* refactor(templates): normalize Templates * refactor(templates): fix types, lint, and tests * fix(ui): update schemas * fix(ui): remove unnecessary processStrategy from templates * fix(ui): lint * fix(ui): update thunks and selectors, and remove errant commentspull/16412/head
parent
21e7eb7841
commit
67829a2b7c
|
@ -24,7 +24,7 @@ import {
|
||||||
import {setViews} from 'src/views/actions/creators'
|
import {setViews} from 'src/views/actions/creators'
|
||||||
import {selectValue} from 'src/variables/actions/creators'
|
import {selectValue} from 'src/variables/actions/creators'
|
||||||
import {getVariables, refreshVariableValues} from 'src/variables/actions/thunks'
|
import {getVariables, refreshVariableValues} from 'src/variables/actions/thunks'
|
||||||
import {setExportTemplate} from 'src/templates/actions'
|
import {setExportTemplate} from 'src/templates/actions/creators'
|
||||||
import {checkDashboardLimits} from 'src/cloud/actions/limits'
|
import {checkDashboardLimits} from 'src/cloud/actions/limits'
|
||||||
import {updateViewAndVariables} from 'src/views/actions/thunks'
|
import {updateViewAndVariables} from 'src/views/actions/thunks'
|
||||||
import * as creators from 'src/dashboards/actions/creators'
|
import * as creators from 'src/dashboards/actions/creators'
|
||||||
|
|
|
@ -7,7 +7,7 @@ import ExportOverlay from 'src/shared/components/ExportOverlay'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {convertToTemplate as convertToTemplateAction} from 'src/dashboards/actions/thunks'
|
import {convertToTemplate as convertToTemplateAction} from 'src/dashboards/actions/thunks'
|
||||||
import {clearExportTemplate as clearExportTemplateAction} from 'src/templates/actions'
|
import {clearExportTemplate as clearExportTemplateAction} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {DocumentCreate} from '@influxdata/influx'
|
import {DocumentCreate} from '@influxdata/influx'
|
||||||
|
@ -62,8 +62,8 @@ class DashboardExportOverlay extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = (state: AppState): StateProps => ({
|
const mstp = (state: AppState): StateProps => ({
|
||||||
dashboardTemplate: state.templates.exportTemplate.item,
|
dashboardTemplate: state.resources.templates.exportTemplate.item,
|
||||||
status: state.templates.exportTemplate.status,
|
status: state.resources.templates.exportTemplate.status,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {getPlugins} from 'src/dataLoaders/actions/telegrafEditor'
|
||||||
import {getScrapers} from 'src/scrapers/actions/thunks'
|
import {getScrapers} from 'src/scrapers/actions/thunks'
|
||||||
import {getTasks} from 'src/tasks/actions/thunks'
|
import {getTasks} from 'src/tasks/actions/thunks'
|
||||||
import {getTelegrafs} from 'src/telegrafs/actions/thunks'
|
import {getTelegrafs} from 'src/telegrafs/actions/thunks'
|
||||||
import {getTemplates} from 'src/templates/actions'
|
import {getTemplates} from 'src/templates/actions/thunks'
|
||||||
import {getVariables} from 'src/variables/actions/thunks'
|
import {getVariables} from 'src/variables/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Types
|
||||||
|
import {AppState, ResourceType} from 'src/types'
|
||||||
|
|
||||||
|
export const getAll = (state: AppState, resource: ResourceType) => {
|
||||||
|
const {resources} = state
|
||||||
|
const allIDs: string[] = resources[resource].allIDs
|
||||||
|
const byID = resources[resource].byID
|
||||||
|
return allIDs.map(id => byID[id])
|
||||||
|
}
|
|
@ -8,14 +8,15 @@ export const getResourcesStatus = (
|
||||||
const statuses = resources.map(resource => {
|
const statuses = resources.map(resource => {
|
||||||
switch (resource) {
|
switch (resource) {
|
||||||
// Normalized resource statuses
|
// Normalized resource statuses
|
||||||
case ResourceType.Members:
|
case ResourceType.Authorizations:
|
||||||
case ResourceType.Buckets:
|
case ResourceType.Buckets:
|
||||||
case ResourceType.Telegrafs:
|
|
||||||
case ResourceType.Tasks:
|
|
||||||
case ResourceType.Scrapers:
|
|
||||||
case ResourceType.Variables:
|
|
||||||
case ResourceType.Dashboards:
|
case ResourceType.Dashboards:
|
||||||
case ResourceType.Authorizations: {
|
case ResourceType.Members:
|
||||||
|
case ResourceType.Scrapers:
|
||||||
|
case ResourceType.Tasks:
|
||||||
|
case ResourceType.Telegrafs:
|
||||||
|
case ResourceType.Templates:
|
||||||
|
case ResourceType.Variables: {
|
||||||
return state.resources[resource].status
|
return state.resources[resource].status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@ import {omit} from 'lodash'
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
Cell,
|
Cell,
|
||||||
ResourceType,
|
Dashboard,
|
||||||
Telegraf,
|
|
||||||
Task,
|
|
||||||
Label,
|
Label,
|
||||||
RemoteDataState,
|
RemoteDataState,
|
||||||
|
ResourceType,
|
||||||
|
Task,
|
||||||
|
Telegraf,
|
||||||
Variable,
|
Variable,
|
||||||
Dashboard,
|
|
||||||
View,
|
View,
|
||||||
} from 'src/types'
|
} from 'src/types'
|
||||||
import {CellsWithViewProperties} from 'src/client'
|
import {CellsWithViewProperties} from 'src/client'
|
||||||
|
@ -176,6 +176,12 @@ export const telegraf = new schema.Entity(
|
||||||
|
|
||||||
export const arrayOfTelegrafs = [telegraf]
|
export const arrayOfTelegrafs = [telegraf]
|
||||||
|
|
||||||
|
/* Templates */
|
||||||
|
|
||||||
|
// Defines the schema for the "templates" resource
|
||||||
|
export const template = new schema.Entity(ResourceType.Templates)
|
||||||
|
export const arrayOfTemplates = [template]
|
||||||
|
|
||||||
/* Scrapers */
|
/* Scrapers */
|
||||||
|
|
||||||
// Defines the schema for the "scrapers" resource
|
// Defines the schema for the "scrapers" resource
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {Controlled as ReactCodeMirror} from 'react-codemirror2'
|
||||||
import CopyButton from 'src/shared/components/CopyButton'
|
import CopyButton from 'src/shared/components/CopyButton'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {createTemplateFromResource} from 'src/templates/actions/'
|
import {createTemplateFromResource} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import {downloadTextFile} from 'src/shared/utils/download'
|
import {downloadTextFile} from 'src/shared/utils/download'
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const formatStatValue = (
|
||||||
value: number | string = 0,
|
value: number | string = 0,
|
||||||
{decimalPlaces, prefix, suffix}: FormatStatValueOptions = {}
|
{decimalPlaces, prefix, suffix}: FormatStatValueOptions = {}
|
||||||
): string => {
|
): string => {
|
||||||
let localeFormattedValue // undefined, string, or number
|
let localeFormattedValue: undefined | string | number
|
||||||
|
|
||||||
if (isNumber(value)) {
|
if (isNumber(value)) {
|
||||||
let digits: number
|
let digits: number
|
||||||
|
|
|
@ -75,6 +75,7 @@ export const rootReducer = combineReducers<ReducerState>({
|
||||||
scrapers: scrapersReducer,
|
scrapers: scrapersReducer,
|
||||||
tasks: tasksReducer,
|
tasks: tasksReducer,
|
||||||
telegrafs: telegrafsReducer,
|
telegrafs: telegrafsReducer,
|
||||||
|
templates: templatesReducer,
|
||||||
tokens: authsReducer,
|
tokens: authsReducer,
|
||||||
variables: variablesReducer,
|
variables: variablesReducer,
|
||||||
views: viewsReducer,
|
views: viewsReducer,
|
||||||
|
@ -84,7 +85,6 @@ export const rootReducer = combineReducers<ReducerState>({
|
||||||
telegrafEditor: editorReducer,
|
telegrafEditor: editorReducer,
|
||||||
telegrafEditorActivePlugins: activePluginsReducer,
|
telegrafEditorActivePlugins: activePluginsReducer,
|
||||||
telegrafEditorPlugins: pluginsReducer,
|
telegrafEditorPlugins: pluginsReducer,
|
||||||
templates: templatesReducer,
|
|
||||||
timeMachines: timeMachinesReducer,
|
timeMachines: timeMachinesReducer,
|
||||||
userSettings: userSettingsReducer,
|
userSettings: userSettingsReducer,
|
||||||
variableEditor: variableEditorReducer,
|
variableEditor: variableEditorReducer,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {createTaskFromTemplate as createTaskFromTemplateAJAX} from 'src/template
|
||||||
import * as schemas from 'src/schemas'
|
import * as schemas from 'src/schemas'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {setExportTemplate} from 'src/templates/actions'
|
import {setExportTemplate} from 'src/templates/actions/creators'
|
||||||
import {notify, Action as NotifyAction} from 'src/shared/actions/notifications'
|
import {notify, Action as NotifyAction} from 'src/shared/actions/notifications'
|
||||||
import {
|
import {
|
||||||
addTask,
|
addTask,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import ExportOverlay from 'src/shared/components/ExportOverlay'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {convertToTemplate as convertToTemplateAction} from 'src/tasks/actions/thunks'
|
import {convertToTemplate as convertToTemplateAction} from 'src/tasks/actions/thunks'
|
||||||
import {clearExportTemplate as clearExportTemplateAction} from 'src/templates/actions'
|
import {clearExportTemplate as clearExportTemplateAction} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {AppState} from 'src/types'
|
import {AppState} from 'src/types'
|
||||||
|
@ -62,8 +62,8 @@ class TaskExportOverlay extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = (state: AppState): StateProps => ({
|
const mstp = (state: AppState): StateProps => ({
|
||||||
taskTemplate: state.templates.exportTemplate.item,
|
taskTemplate: state.resources.templates.exportTemplate.item,
|
||||||
status: state.templates.exportTemplate.status,
|
status: state.resources.templates.exportTemplate.status,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import GetResources from 'src/resources/components/GetResources'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {createTaskFromTemplate as createTaskFromTemplateAction} from 'src/tasks/actions/thunks'
|
import {createTaskFromTemplate as createTaskFromTemplateAction} from 'src/tasks/actions/thunks'
|
||||||
import {getTemplateByID} from 'src/templates/actions'
|
import {getTemplateByID} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
|
@ -30,6 +30,9 @@ import {
|
||||||
ResourceType,
|
ResourceType,
|
||||||
} from 'src/types'
|
} from 'src/types'
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
import {getAll} from 'src/resources/selectors/getAll'
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
templates: TemplateSummary[]
|
templates: TemplateSummary[]
|
||||||
templateStatus: RemoteDataState
|
templateStatus: RemoteDataState
|
||||||
|
@ -138,7 +141,13 @@ class TaskImportFromTemplateOverlay extends PureComponent<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = ({templates: {items, status}}: AppState): StateProps => {
|
const mstp = (state: AppState): StateProps => {
|
||||||
|
const {
|
||||||
|
resources: {
|
||||||
|
templates: {status},
|
||||||
|
},
|
||||||
|
} = state
|
||||||
|
const items = getAll(state, ResourceType.Templates)
|
||||||
const filteredTemplates = items.filter(
|
const filteredTemplates = items.filter(
|
||||||
t => !t.meta.type || t.meta.type === TemplateType.Task
|
t => !t.meta.type || t.meta.type === TemplateType.Task
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
// Types
|
||||||
|
import {RemoteDataState, TemplateSummaryEntities} from 'src/types'
|
||||||
|
import {DocumentCreate} from '@influxdata/influx'
|
||||||
|
import {NormalizedSchema} from 'normalizr'
|
||||||
|
|
||||||
|
export const ADD_TEMPLATE_SUMMARY = 'ADD_TEMPLATE_SUMMARY'
|
||||||
|
export const GET_TEMPLATE_SUMMARIES_FOR_ORG = 'GET_TEMPLATE_SUMMARIES_FOR_ORG'
|
||||||
|
export const POPULATE_TEMPLATE_SUMMARIES = 'POPULATE_TEMPLATE_SUMMARIES'
|
||||||
|
export const REMOVE_TEMPLATE_SUMMARY = 'REMOVE_TEMPLATE_SUMMARY'
|
||||||
|
export const SET_EXPORT_TEMPLATE = 'SET_EXPORT_TEMPLATE'
|
||||||
|
export const SET_TEMPLATE_SUMMARY = 'SET_TEMPLATE_SUMMARY'
|
||||||
|
export const SET_TEMPLATES_STATUS = 'SET_TEMPLATES_STATUS'
|
||||||
|
|
||||||
|
export type Action =
|
||||||
|
| ReturnType<typeof addTemplateSummary>
|
||||||
|
| ReturnType<typeof populateTemplateSummaries>
|
||||||
|
| ReturnType<typeof removeTemplateSummary>
|
||||||
|
| ReturnType<typeof setExportTemplate>
|
||||||
|
| ReturnType<typeof setTemplatesStatus>
|
||||||
|
| ReturnType<typeof setTemplateSummary>
|
||||||
|
|
||||||
|
type TemplateSummarySchema<R extends string | string[]> = NormalizedSchema<
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
R
|
||||||
|
>
|
||||||
|
|
||||||
|
// Action Creators
|
||||||
|
export const addTemplateSummary = (schema: TemplateSummarySchema<string>) =>
|
||||||
|
({
|
||||||
|
type: ADD_TEMPLATE_SUMMARY,
|
||||||
|
schema,
|
||||||
|
} as const)
|
||||||
|
|
||||||
|
export const populateTemplateSummaries = (
|
||||||
|
schema: TemplateSummarySchema<string[]>
|
||||||
|
) =>
|
||||||
|
({
|
||||||
|
type: POPULATE_TEMPLATE_SUMMARIES,
|
||||||
|
status: RemoteDataState.Done,
|
||||||
|
schema,
|
||||||
|
} as const)
|
||||||
|
|
||||||
|
export const setExportTemplate = (
|
||||||
|
status: RemoteDataState,
|
||||||
|
item?: DocumentCreate
|
||||||
|
) =>
|
||||||
|
({
|
||||||
|
type: SET_EXPORT_TEMPLATE,
|
||||||
|
status,
|
||||||
|
item,
|
||||||
|
} as const)
|
||||||
|
|
||||||
|
export const setTemplatesStatus = (status: RemoteDataState) =>
|
||||||
|
({
|
||||||
|
type: SET_TEMPLATES_STATUS,
|
||||||
|
status,
|
||||||
|
} as const)
|
||||||
|
|
||||||
|
export const removeTemplateSummary = (id: string) =>
|
||||||
|
({
|
||||||
|
type: REMOVE_TEMPLATE_SUMMARY,
|
||||||
|
id,
|
||||||
|
} as const)
|
||||||
|
|
||||||
|
export const setTemplateSummary = (
|
||||||
|
id: string,
|
||||||
|
status: RemoteDataState,
|
||||||
|
schema?: TemplateSummarySchema<string>
|
||||||
|
) =>
|
||||||
|
({
|
||||||
|
type: SET_TEMPLATE_SUMMARY,
|
||||||
|
id,
|
||||||
|
status,
|
||||||
|
schema,
|
||||||
|
} as const)
|
|
@ -1,136 +1,84 @@
|
||||||
// Utils
|
// Libraries
|
||||||
import {templateToExport} from 'src/shared/utils/resourceToTemplate'
|
import {normalize} from 'normalizr'
|
||||||
|
|
||||||
|
// APIs
|
||||||
|
import {client} from 'src/utils/api'
|
||||||
|
import {createDashboardFromTemplate} from 'src/dashboards/actions/thunks'
|
||||||
|
import {createVariableFromTemplate} from 'src/variables/actions/thunks'
|
||||||
|
import {createTaskFromTemplate} from 'src/tasks/actions/thunks'
|
||||||
|
|
||||||
|
// Schemas
|
||||||
|
import * as schemas from 'src/schemas'
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
import {notify, Action as NotifyAction} from 'src/shared/actions/notifications'
|
||||||
|
import {
|
||||||
|
addTemplateSummary,
|
||||||
|
populateTemplateSummaries,
|
||||||
|
setExportTemplate,
|
||||||
|
setTemplatesStatus,
|
||||||
|
removeTemplateSummary,
|
||||||
|
setTemplateSummary,
|
||||||
|
Action as TemplateAction,
|
||||||
|
} from 'src/templates/actions/creators'
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
import * as copy from 'src/shared/copy/notifications'
|
||||||
import {staticTemplates} from 'src/templates/constants/defaultTemplates'
|
import {staticTemplates} from 'src/templates/constants/defaultTemplates'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {Dispatch} from 'react'
|
||||||
TemplateSummary,
|
import {DocumentCreate, ITaskTemplate, TemplateType} from '@influxdata/influx'
|
||||||
DocumentCreate,
|
|
||||||
ITaskTemplate,
|
|
||||||
TemplateType,
|
|
||||||
ITemplate,
|
|
||||||
} from '@influxdata/influx'
|
|
||||||
import {
|
import {
|
||||||
RemoteDataState,
|
RemoteDataState,
|
||||||
GetState,
|
GetState,
|
||||||
DashboardTemplate,
|
DashboardTemplate,
|
||||||
VariableTemplate,
|
VariableTemplate,
|
||||||
Template,
|
Template,
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
Label,
|
Label,
|
||||||
} from 'src/types'
|
} from 'src/types'
|
||||||
|
|
||||||
// Actions
|
// Utils
|
||||||
import {notify} from 'src/shared/actions/notifications'
|
import {templateToExport} from 'src/shared/utils/resourceToTemplate'
|
||||||
|
|
||||||
// Constants
|
|
||||||
import * as copy from 'src/shared/copy/notifications'
|
|
||||||
|
|
||||||
// API
|
|
||||||
import {client} from 'src/utils/api'
|
|
||||||
import {createDashboardFromTemplate} from 'src/dashboards/actions/thunks'
|
|
||||||
import {createVariableFromTemplate} from 'src/variables/actions/thunks'
|
|
||||||
import {createTaskFromTemplate} from 'src/tasks/actions/thunks'
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
import {getOrg} from 'src/organizations/selectors'
|
import {getOrg} from 'src/organizations/selectors'
|
||||||
|
|
||||||
export enum ActionTypes {
|
type Action = TemplateAction | NotifyAction
|
||||||
GetTemplateSummariesForOrg = 'GET_TEMPLATE_SUMMARIES_FOR_ORG',
|
|
||||||
PopulateTemplateSummaries = 'POPULATE_TEMPLATE_SUMMARIES',
|
|
||||||
SetTemplatesStatus = 'SET_TEMPLATES_STATUS',
|
|
||||||
SetExportTemplate = 'SET_EXPORT_TEMPLATE',
|
|
||||||
RemoveTemplateSummary = 'REMOVE_TEMPLATE_SUMMARY',
|
|
||||||
AddTemplateSummary = 'ADD_TEMPLATE_SUMMARY',
|
|
||||||
SetTemplateSummary = 'SET_TEMPLATE_SUMMARY',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Actions =
|
export const getTemplateByID = async (id: string): Promise<Template> => {
|
||||||
| PopulateTemplateSummaries
|
|
||||||
| SetTemplatesStatus
|
|
||||||
| SetExportTemplate
|
|
||||||
| RemoveTemplateSummary
|
|
||||||
| AddTemplateSummary
|
|
||||||
| SetTemplateSummary
|
|
||||||
|
|
||||||
export interface AddTemplateSummary {
|
|
||||||
type: ActionTypes.AddTemplateSummary
|
|
||||||
payload: {item: TemplateSummary}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const addTemplateSummary = (
|
|
||||||
item: TemplateSummary
|
|
||||||
): AddTemplateSummary => ({
|
|
||||||
type: ActionTypes.AddTemplateSummary,
|
|
||||||
payload: {item},
|
|
||||||
})
|
|
||||||
|
|
||||||
export interface PopulateTemplateSummaries {
|
|
||||||
type: ActionTypes.PopulateTemplateSummaries
|
|
||||||
payload: {items: TemplateSummary[]; status: RemoteDataState}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const populateTemplateSummaries = (
|
|
||||||
items: TemplateSummary[]
|
|
||||||
): PopulateTemplateSummaries => ({
|
|
||||||
type: ActionTypes.PopulateTemplateSummaries,
|
|
||||||
payload: {items, status: RemoteDataState.Done},
|
|
||||||
})
|
|
||||||
|
|
||||||
export interface SetTemplatesStatus {
|
|
||||||
type: ActionTypes.SetTemplatesStatus
|
|
||||||
payload: {status: RemoteDataState}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setTemplatesStatus = (
|
|
||||||
status: RemoteDataState
|
|
||||||
): SetTemplatesStatus => ({
|
|
||||||
type: ActionTypes.SetTemplatesStatus,
|
|
||||||
payload: {status},
|
|
||||||
})
|
|
||||||
|
|
||||||
export interface SetExportTemplate {
|
|
||||||
type: ActionTypes.SetExportTemplate
|
|
||||||
payload: {status: RemoteDataState; item?: DocumentCreate}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setExportTemplate = (
|
|
||||||
status: RemoteDataState,
|
|
||||||
item?: DocumentCreate
|
|
||||||
): SetExportTemplate => ({
|
|
||||||
type: ActionTypes.SetExportTemplate,
|
|
||||||
payload: {status, item},
|
|
||||||
})
|
|
||||||
|
|
||||||
interface RemoveTemplateSummary {
|
|
||||||
type: ActionTypes.RemoveTemplateSummary
|
|
||||||
payload: {templateID: string}
|
|
||||||
}
|
|
||||||
|
|
||||||
const removeTemplateSummary = (templateID: string): RemoveTemplateSummary => ({
|
|
||||||
type: ActionTypes.RemoveTemplateSummary,
|
|
||||||
payload: {templateID},
|
|
||||||
})
|
|
||||||
|
|
||||||
export const getTemplateByID = async (id: string) => {
|
|
||||||
const template = (await client.templates.get(id)) as Template
|
const template = (await client.templates.get(id)) as Template
|
||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getTemplates = () => async (dispatch, getState: GetState) => {
|
export const getTemplates = () => async (
|
||||||
|
dispatch: Dispatch<Action>,
|
||||||
|
getState: GetState
|
||||||
|
): Promise<void> => {
|
||||||
const org = getOrg(getState())
|
const org = getOrg(getState())
|
||||||
dispatch(setTemplatesStatus(RemoteDataState.Loading))
|
dispatch(setTemplatesStatus(RemoteDataState.Loading))
|
||||||
const items = await client.templates.getAll(org.id)
|
const items = await client.templates.getAll(org.id)
|
||||||
dispatch(populateTemplateSummaries(items))
|
const templateSummaries = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string[]
|
||||||
|
>(items, schemas.arrayOfTemplates)
|
||||||
|
dispatch(populateTemplateSummaries(templateSummaries))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createTemplate = (template: DocumentCreate) => async (
|
export const createTemplate = (template: DocumentCreate) => async (
|
||||||
dispatch,
|
dispatch: Dispatch<Action>,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const org = getOrg(getState())
|
const org = getOrg(getState())
|
||||||
await client.templates.create({...template, orgID: org.id})
|
const item = await client.templates.create({...template, orgID: org.id})
|
||||||
|
const templateSummary = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string
|
||||||
|
>(item, schemas.template)
|
||||||
|
dispatch(addTemplateSummary(templateSummary))
|
||||||
dispatch(notify(copy.importTemplateSucceeded()))
|
dispatch(notify(copy.importTemplateSucceeded()))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
@ -141,37 +89,30 @@ export const createTemplate = (template: DocumentCreate) => async (
|
||||||
export const createTemplateFromResource = (
|
export const createTemplateFromResource = (
|
||||||
resource: DocumentCreate,
|
resource: DocumentCreate,
|
||||||
resourceName: string
|
resourceName: string
|
||||||
) => async (dispatch, getState: GetState) => {
|
) => async (dispatch: Dispatch<Action>, getState: GetState) => {
|
||||||
try {
|
try {
|
||||||
const org = getOrg(getState())
|
const org = getOrg(getState())
|
||||||
await client.templates.create({...resource, orgID: org.id})
|
await client.templates.create({...resource, orgID: org.id})
|
||||||
dispatch(notify(copy.resourceSavedAsTemplate(resourceName)))
|
dispatch(notify(copy.resourceSavedAsTemplate(resourceName)))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
dispatch(copy.saveResourceAsTemplateFailed(resourceName, e))
|
dispatch(notify(copy.saveResourceAsTemplateFailed(resourceName, e)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SetTemplateSummary {
|
|
||||||
type: ActionTypes.SetTemplateSummary
|
|
||||||
payload: {id: string; templateSummary: TemplateSummary}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setTemplateSummary = (
|
|
||||||
id: string,
|
|
||||||
templateSummary: TemplateSummary
|
|
||||||
): SetTemplateSummary => ({
|
|
||||||
type: ActionTypes.SetTemplateSummary,
|
|
||||||
payload: {id, templateSummary},
|
|
||||||
})
|
|
||||||
|
|
||||||
export const updateTemplate = (id: string, props: TemplateSummary) => async (
|
export const updateTemplate = (id: string, props: TemplateSummary) => async (
|
||||||
dispatch
|
dispatch: Dispatch<Action>
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
|
setTemplateSummary(id, RemoteDataState.Loading)
|
||||||
try {
|
try {
|
||||||
const {meta} = await client.templates.update(id, props)
|
const item = await client.templates.update(id, props)
|
||||||
|
const templateSummary = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string
|
||||||
|
>(item, schemas.template)
|
||||||
|
|
||||||
dispatch(setTemplateSummary(id, {...props, meta}))
|
dispatch(setTemplateSummary(id, RemoteDataState.Done, templateSummary))
|
||||||
dispatch(notify(copy.updateTemplateSucceeded()))
|
dispatch(notify(copy.updateTemplateSucceeded()))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
@ -180,7 +121,7 @@ export const updateTemplate = (id: string, props: TemplateSummary) => async (
|
||||||
}
|
}
|
||||||
|
|
||||||
export const convertToTemplate = (id: string) => async (
|
export const convertToTemplate = (id: string) => async (
|
||||||
dispatch
|
dispatch: Dispatch<Action>
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
dispatch(setExportTemplate(RemoteDataState.Loading))
|
dispatch(setExportTemplate(RemoteDataState.Loading))
|
||||||
|
@ -195,12 +136,12 @@ export const convertToTemplate = (id: string) => async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clearExportTemplate = () => dispatch => {
|
export const clearExportTemplate = () => (dispatch: Dispatch<Action>) => {
|
||||||
dispatch(setExportTemplate(RemoteDataState.NotStarted, null))
|
dispatch(setExportTemplate(RemoteDataState.NotStarted, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deleteTemplate = (templateID: string) => async (
|
export const deleteTemplate = (templateID: string) => async (
|
||||||
dispatch
|
dispatch: Dispatch<Action>
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
await client.templates.delete(templateID)
|
await client.templates.delete(templateID)
|
||||||
|
@ -213,19 +154,19 @@ export const deleteTemplate = (templateID: string) => async (
|
||||||
}
|
}
|
||||||
|
|
||||||
export const cloneTemplate = (templateID: string) => async (
|
export const cloneTemplate = (templateID: string) => async (
|
||||||
dispatch,
|
dispatch: Dispatch<Action>,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const org = getOrg(getState())
|
const org = getOrg(getState())
|
||||||
const createdTemplate = await client.templates.clone(templateID, org.id)
|
const createdTemplate = await client.templates.clone(templateID, org.id)
|
||||||
|
const templateSummary = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string
|
||||||
|
>(createdTemplate, schemas.template)
|
||||||
|
|
||||||
dispatch(
|
dispatch(addTemplateSummary(templateSummary))
|
||||||
addTemplateSummary({
|
|
||||||
...createdTemplate,
|
|
||||||
labels: createdTemplate.labels || [],
|
|
||||||
})
|
|
||||||
)
|
|
||||||
dispatch(notify(copy.cloneTemplateSuccess()))
|
dispatch(notify(copy.cloneTemplateSuccess()))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
@ -276,12 +217,19 @@ export const createResourceFromTemplate = (templateID: string) => async (
|
||||||
export const addTemplateLabelsAsync = (
|
export const addTemplateLabelsAsync = (
|
||||||
templateID: string,
|
templateID: string,
|
||||||
labels: Label[]
|
labels: Label[]
|
||||||
) => async (dispatch): Promise<void> => {
|
) => async (dispatch: Dispatch<Action>): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
await client.templates.addLabels(templateID, labels.map(l => l.id))
|
await client.templates.addLabels(templateID, labels.map(l => l.id))
|
||||||
const template = await client.templates.get(templateID)
|
const item = await client.templates.get(templateID)
|
||||||
|
const templateSummary = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string
|
||||||
|
>(item, schemas.template)
|
||||||
|
|
||||||
dispatch(setTemplateSummary(templateID, templateToSummary(template)))
|
dispatch(
|
||||||
|
setTemplateSummary(templateID, RemoteDataState.Done, templateSummary)
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
dispatch(notify(copy.addTemplateLabelFailed()))
|
dispatch(notify(copy.addTemplateLabelFailed()))
|
||||||
|
@ -291,20 +239,21 @@ export const addTemplateLabelsAsync = (
|
||||||
export const removeTemplateLabelsAsync = (
|
export const removeTemplateLabelsAsync = (
|
||||||
templateID: string,
|
templateID: string,
|
||||||
labels: Label[]
|
labels: Label[]
|
||||||
) => async (dispatch): Promise<void> => {
|
) => async (dispatch: Dispatch<Action>): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
await client.templates.removeLabels(templateID, labels.map(l => l.id))
|
await client.templates.removeLabels(templateID, labels.map(l => l.id))
|
||||||
const template = await client.templates.get(templateID)
|
const item = await client.templates.get(templateID)
|
||||||
|
const templateSummary = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string
|
||||||
|
>(item, schemas.template)
|
||||||
|
|
||||||
dispatch(setTemplateSummary(templateID, templateToSummary(template)))
|
dispatch(
|
||||||
|
setTemplateSummary(templateID, RemoteDataState.Done, templateSummary)
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
dispatch(notify(copy.removeTemplateLabelFailed()))
|
dispatch(notify(copy.removeTemplateLabelFailed()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateToSummary = (template: ITemplate): TemplateSummary => ({
|
|
||||||
id: template.id,
|
|
||||||
meta: template.meta,
|
|
||||||
labels: template.labels,
|
|
||||||
})
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
import {ResourceCard} from '@influxdata/clockface'
|
import {ResourceCard} from '@influxdata/clockface'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {createResourceFromStaticTemplate} from 'src/templates/actions'
|
import {createResourceFromStaticTemplate} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
import {viewableLabels} from 'src/labels/selectors'
|
import {viewableLabels} from 'src/labels/selectors'
|
||||||
|
|
|
@ -24,16 +24,15 @@ import {
|
||||||
createResourceFromTemplate,
|
createResourceFromTemplate,
|
||||||
removeTemplateLabelsAsync,
|
removeTemplateLabelsAsync,
|
||||||
addTemplateLabelsAsync,
|
addTemplateLabelsAsync,
|
||||||
} from 'src/templates/actions'
|
} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
import {viewableLabels} from 'src/labels/selectors'
|
import {viewableLabels} from 'src/labels/selectors'
|
||||||
import {getOrg} from 'src/organizations/selectors'
|
import {getOrg} from 'src/organizations/selectors'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {TemplateSummary} from '@influxdata/influx'
|
|
||||||
import {ComponentColor} from '@influxdata/clockface'
|
import {ComponentColor} from '@influxdata/clockface'
|
||||||
import {AppState, Organization, Label} from 'src/types'
|
import {AppState, Organization, Label, TemplateSummary} from 'src/types'
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import {DEFAULT_TEMPLATE_NAME} from 'src/templates/constants'
|
import {DEFAULT_TEMPLATE_NAME} from 'src/templates/constants'
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ExportOverlay from 'src/shared/components/ExportOverlay'
|
||||||
import {
|
import {
|
||||||
convertToTemplate as convertToTemplateAction,
|
convertToTemplate as convertToTemplateAction,
|
||||||
clearExportTemplate as clearExportTemplateAction,
|
clearExportTemplate as clearExportTemplateAction,
|
||||||
} from 'src/templates/actions'
|
} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {DocumentCreate} from '@influxdata/influx'
|
import {DocumentCreate} from '@influxdata/influx'
|
||||||
|
@ -63,8 +63,8 @@ class TemplateExportOverlay extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = (state: AppState): StateProps => ({
|
const mstp = (state: AppState): StateProps => ({
|
||||||
exportTemplate: state.templates.exportTemplate.item,
|
exportTemplate: state.resources.templates.exportTemplate.item,
|
||||||
status: state.templates.exportTemplate.status,
|
status: state.resources.templates.exportTemplate.status,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
|
|
|
@ -9,10 +9,7 @@ import ImportOverlay from 'src/shared/components/ImportOverlay'
|
||||||
import {invalidJSON} from 'src/shared/copy/notifications'
|
import {invalidJSON} from 'src/shared/copy/notifications'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {
|
import {createTemplate as createTemplateAction} from 'src/templates/actions/thunks'
|
||||||
createTemplate as createTemplateAction,
|
|
||||||
getTemplates as getTemplatesAction,
|
|
||||||
} from 'src/templates/actions'
|
|
||||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
@ -29,7 +26,6 @@ interface State {
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
createTemplate: typeof createTemplateAction
|
createTemplate: typeof createTemplateAction
|
||||||
getTemplates: typeof getTemplatesAction
|
|
||||||
notify: typeof notifyAction
|
notify: typeof notifyAction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +66,7 @@ class TemplateImportOverlay extends PureComponent<Props> {
|
||||||
this.setState(() => ({status}))
|
this.setState(() => ({status}))
|
||||||
|
|
||||||
private handleImportTemplate = (importString: string) => {
|
private handleImportTemplate = (importString: string) => {
|
||||||
const {createTemplate, getTemplates, notify} = this.props
|
const {createTemplate, notify} = this.props
|
||||||
|
|
||||||
let template
|
let template
|
||||||
this.updateOverlayStatus(ComponentStatus.Default)
|
this.updateOverlayStatus(ComponentStatus.Default)
|
||||||
|
@ -82,9 +78,6 @@ class TemplateImportOverlay extends PureComponent<Props> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
createTemplate(template)
|
createTemplate(template)
|
||||||
|
|
||||||
getTemplates()
|
|
||||||
|
|
||||||
this.onDismiss()
|
this.onDismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +95,6 @@ const mstp = (state: AppState, props: Props): StateProps => {
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
notify: notifyAction,
|
notify: notifyAction,
|
||||||
createTemplate: createTemplateAction,
|
createTemplate: createTemplateAction,
|
||||||
getTemplates: getTemplatesAction,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect<StateProps, DispatchProps, Props>(
|
export default connect<StateProps, DispatchProps, Props>(
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import {
|
import {
|
||||||
convertToTemplate as convertToTemplateAction,
|
convertToTemplate as convertToTemplateAction,
|
||||||
clearExportTemplate as clearExportTemplateAction,
|
clearExportTemplate as clearExportTemplateAction,
|
||||||
} from 'src/templates/actions'
|
} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {DocumentCreate} from '@influxdata/influx'
|
import {DocumentCreate} from '@influxdata/influx'
|
||||||
|
@ -74,8 +74,8 @@ class TemplateExportOverlay extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = (state: AppState): StateProps => ({
|
const mstp = (state: AppState): StateProps => ({
|
||||||
exportTemplate: state.templates.exportTemplate.item,
|
exportTemplate: state.resources.templates.exportTemplate.item,
|
||||||
status: state.templates.exportTemplate.status,
|
status: state.resources.templates.exportTemplate.status,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import EmptyTemplatesList from 'src/templates/components/EmptyTemplatesList'
|
||||||
import TemplateCard from 'src/templates/components/TemplateCard'
|
import TemplateCard from 'src/templates/components/TemplateCard'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {TemplateSummary} from '@influxdata/influx'
|
import {TemplateSummary} from 'src/types'
|
||||||
import {SortTypes} from 'src/shared/utils/sort'
|
import {SortTypes} from 'src/shared/utils/sort'
|
||||||
import {Sort} from 'src/clockface'
|
import {Sort} from 'src/clockface'
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import GetResources from 'src/resources/components/GetResources'
|
||||||
import SettingsTabbedPageHeader from 'src/settings/components/SettingsTabbedPageHeader'
|
import SettingsTabbedPageHeader from 'src/settings/components/SettingsTabbedPageHeader'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {TemplateSummary, AppState, ResourceType} from 'src/types'
|
import {AppState, ResourceType, Template, TemplateSummary} from 'src/types'
|
||||||
import {SortTypes} from 'src/shared/utils/sort'
|
import {SortTypes} from 'src/shared/utils/sort'
|
||||||
import {
|
import {
|
||||||
Sort,
|
Sort,
|
||||||
|
@ -28,14 +28,19 @@ import {
|
||||||
|
|
||||||
import {staticTemplates as statics} from 'src/templates/constants/defaultTemplates'
|
import {staticTemplates as statics} from 'src/templates/constants/defaultTemplates'
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
import {getAll} from 'src/resources/selectors/getAll'
|
||||||
|
|
||||||
|
type TemplateOrSummary = Template | TemplateSummary
|
||||||
|
|
||||||
interface StaticTemplate {
|
interface StaticTemplate {
|
||||||
name: string
|
name: string
|
||||||
template: TemplateSummary
|
template: TemplateOrSummary
|
||||||
}
|
}
|
||||||
|
|
||||||
const staticTemplates: StaticTemplate[] = _.map(statics, (template, name) => ({
|
const staticTemplates: StaticTemplate[] = _.map(statics, (template, name) => ({
|
||||||
name,
|
name,
|
||||||
template: template as TemplateSummary,
|
template: template as TemplateOrSummary,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
|
@ -198,8 +203,8 @@ class TemplatesPage extends PureComponent<Props, State> {
|
||||||
this.setState({searchTerm})
|
this.setState({searchTerm})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const mstp = ({templates}: AppState): StateProps => ({
|
const mstp = (state: AppState): StateProps => ({
|
||||||
templates: templates.items,
|
templates: getAll(state, ResourceType.Templates),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect<StateProps, {}, {}>(
|
export default connect<StateProps, {}, {}>(
|
||||||
|
|
|
@ -17,7 +17,7 @@ import GetResources from 'src/resources/components/GetResources'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {createDashboardFromTemplate as createDashboardFromTemplateAction} from 'src/dashboards/actions/thunks'
|
import {createDashboardFromTemplate as createDashboardFromTemplateAction} from 'src/dashboards/actions/thunks'
|
||||||
import {getTemplateByID} from 'src/templates/actions'
|
import {getTemplateByID} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
import {influxdbTemplateList} from 'src/templates/constants/defaultTemplates'
|
import {influxdbTemplateList} from 'src/templates/constants/defaultTemplates'
|
||||||
|
@ -34,6 +34,9 @@ import {
|
||||||
ResourceType,
|
ResourceType,
|
||||||
} from 'src/types'
|
} from 'src/types'
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
import {getAll} from 'src/resources/selectors/getAll'
|
||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
templates: TemplateSummary[]
|
templates: TemplateSummary[]
|
||||||
templateStatus: RemoteDataState
|
templateStatus: RemoteDataState
|
||||||
|
@ -186,7 +189,13 @@ class DashboardImportFromTemplateOverlay extends PureComponent<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = ({templates: {items, status}}: AppState): StateProps => {
|
const mstp = (state: AppState): StateProps => {
|
||||||
|
const {
|
||||||
|
resources: {
|
||||||
|
templates: {status},
|
||||||
|
},
|
||||||
|
} = state
|
||||||
|
const items = getAll(state, ResourceType.Templates)
|
||||||
const filteredTemplates = items.filter(
|
const filteredTemplates = items.filter(
|
||||||
t => !t.meta.type || t.meta.type === TemplateType.Dashboard
|
t => !t.meta.type || t.meta.type === TemplateType.Dashboard
|
||||||
)
|
)
|
||||||
|
@ -196,7 +205,7 @@ const mstp = ({templates: {items, status}}: AppState): StateProps => {
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
templates: [...templates, ...(influxdbTemplateList as TemplateSummary[])],
|
templates: [...templates, ...(influxdbTemplateList as any)],
|
||||||
templateStatus: status,
|
templateStatus: status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,117 @@
|
||||||
import templatesReducer, {defaultState} from 'src/templates/reducers'
|
// Libraries
|
||||||
import {setTemplateSummary} from 'src/templates/actions'
|
import {normalize} from 'normalizr'
|
||||||
|
|
||||||
describe('templatesReducer', () => {
|
// Schema
|
||||||
describe('setTemplateSummary', () => {
|
import * as schemas from 'src/schemas'
|
||||||
it('can update the name of a template', () => {
|
|
||||||
const initialState = defaultState()
|
// Reducer
|
||||||
const initialTemplate = {
|
import {templatesReducer as reducer} from 'src/templates/reducers'
|
||||||
id: 'abc',
|
|
||||||
|
// Actions
|
||||||
|
import {
|
||||||
|
addTemplateSummary,
|
||||||
|
populateTemplateSummaries,
|
||||||
|
removeTemplateSummary,
|
||||||
|
setTemplateSummary,
|
||||||
|
} from 'src/templates/actions/creators'
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import {
|
||||||
|
RemoteDataState,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
TemplateSummary,
|
||||||
|
} from 'src/types'
|
||||||
|
|
||||||
|
const status = RemoteDataState.Done
|
||||||
|
|
||||||
|
const templateSummary = {
|
||||||
|
links: {
|
||||||
|
self: '/api/v2/documents/templates/051ff6b3a8d23000',
|
||||||
|
},
|
||||||
|
id: '1',
|
||||||
|
meta: {
|
||||||
|
name: 'foo',
|
||||||
|
type: 'dashboard',
|
||||||
|
description: 'A template dashboard for something',
|
||||||
|
version: '1',
|
||||||
|
},
|
||||||
labels: [],
|
labels: [],
|
||||||
meta: {name: 'Belcalis', version: '1'},
|
status,
|
||||||
}
|
}
|
||||||
initialState.items.push(initialTemplate)
|
|
||||||
|
|
||||||
const actual = templatesReducer(
|
const exportTemplate = {status, item: null}
|
||||||
initialState,
|
|
||||||
setTemplateSummary(initialTemplate.id, {
|
const initialState = () => ({
|
||||||
...initialTemplate,
|
status,
|
||||||
meta: {...initialTemplate.meta, name: 'Cardi B'},
|
byID: {
|
||||||
|
['1']: templateSummary,
|
||||||
|
['2']: {...templateSummary, id: '2'},
|
||||||
|
},
|
||||||
|
allIDs: [templateSummary.id, '2'],
|
||||||
|
exportTemplate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('templates reducer', () => {
|
||||||
|
it('can set the templatess', () => {
|
||||||
|
const schema = normalize<
|
||||||
|
TemplateSummary,
|
||||||
|
TemplateSummaryEntities,
|
||||||
|
string[]
|
||||||
|
>([templateSummary], schemas.arrayOfTemplates)
|
||||||
|
|
||||||
|
const byID = schema.entities.templates
|
||||||
|
const allIDs = schema.result
|
||||||
|
|
||||||
|
const actual = reducer(undefined, populateTemplateSummaries(schema))
|
||||||
|
|
||||||
|
expect(actual.byID).toEqual(byID)
|
||||||
|
expect(actual.allIDs).toEqual(allIDs)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can add a template', () => {
|
||||||
|
const id = '3'
|
||||||
|
const anotherTemplateSummary = {...templateSummary, id}
|
||||||
|
const schema = normalize<TemplateSummary, TemplateSummaryEntities, string>(
|
||||||
|
anotherTemplateSummary,
|
||||||
|
schemas.template
|
||||||
)
|
)
|
||||||
|
|
||||||
const expected = {
|
const state = initialState()
|
||||||
...defaultState(),
|
|
||||||
items: [
|
const actual = reducer(state, addTemplateSummary(schema))
|
||||||
{
|
|
||||||
...initialTemplate,
|
expect(actual.allIDs.length).toEqual(Number(id))
|
||||||
meta: {...initialTemplate.meta, name: 'Cardi B'},
|
})
|
||||||
},
|
|
||||||
],
|
it('can remove a template', () => {
|
||||||
}
|
const allIDs = [templateSummary.id]
|
||||||
|
const byID = {[templateSummary.id]: templateSummary}
|
||||||
|
|
||||||
|
const state = initialState()
|
||||||
|
const expected = {status, byID, allIDs, exportTemplate}
|
||||||
|
const actual = reducer(state, removeTemplateSummary(state.allIDs[1]))
|
||||||
|
|
||||||
expect(actual).toEqual(expected)
|
expect(actual).toEqual(expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('can set a template', () => {
|
||||||
|
const name = 'updated name'
|
||||||
|
const loadedTemplateSummary = {
|
||||||
|
...templateSummary,
|
||||||
|
meta: {...templateSummary.meta, name: 'updated name'},
|
||||||
|
}
|
||||||
|
const schema = normalize<TemplateSummary, TemplateSummaryEntities, string>(
|
||||||
|
loadedTemplateSummary,
|
||||||
|
schemas.template
|
||||||
|
)
|
||||||
|
|
||||||
|
const state = initialState()
|
||||||
|
|
||||||
|
const actual = reducer(
|
||||||
|
state,
|
||||||
|
setTemplateSummary(templateSummary.id, RemoteDataState.Done, schema)
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(actual.byID[templateSummary.id].meta.name).toEqual(name)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,17 +1,30 @@
|
||||||
import {produce} from 'immer'
|
import {produce} from 'immer'
|
||||||
import {Actions, ActionTypes} from 'src/templates/actions/'
|
import {
|
||||||
import {TemplateSummary, DocumentCreate} from '@influxdata/influx'
|
Action,
|
||||||
import {RemoteDataState} from 'src/types'
|
ADD_TEMPLATE_SUMMARY,
|
||||||
|
POPULATE_TEMPLATE_SUMMARIES,
|
||||||
export interface TemplatesState {
|
REMOVE_TEMPLATE_SUMMARY,
|
||||||
status: RemoteDataState
|
SET_EXPORT_TEMPLATE,
|
||||||
items: TemplateSummary[]
|
SET_TEMPLATE_SUMMARY,
|
||||||
exportTemplate: {status: RemoteDataState; item: DocumentCreate}
|
SET_TEMPLATES_STATUS,
|
||||||
}
|
} from 'src/templates/actions/creators'
|
||||||
|
import {
|
||||||
|
ResourceType,
|
||||||
|
RemoteDataState,
|
||||||
|
TemplateSummary,
|
||||||
|
TemplatesState,
|
||||||
|
} from 'src/types'
|
||||||
|
import {
|
||||||
|
addResource,
|
||||||
|
removeResource,
|
||||||
|
setResource,
|
||||||
|
setResourceAtID,
|
||||||
|
} from 'src/resources/reducers/helpers'
|
||||||
|
|
||||||
export const defaultState = (): TemplatesState => ({
|
export const defaultState = (): TemplatesState => ({
|
||||||
status: RemoteDataState.NotStarted,
|
status: RemoteDataState.NotStarted,
|
||||||
items: [],
|
byID: {},
|
||||||
|
allIDs: [],
|
||||||
exportTemplate: {
|
exportTemplate: {
|
||||||
status: RemoteDataState.NotStarted,
|
status: RemoteDataState.NotStarted,
|
||||||
item: null,
|
item: null,
|
||||||
|
@ -20,43 +33,34 @@ export const defaultState = (): TemplatesState => ({
|
||||||
|
|
||||||
export const templatesReducer = (
|
export const templatesReducer = (
|
||||||
state: TemplatesState = defaultState(),
|
state: TemplatesState = defaultState(),
|
||||||
action: Actions
|
action: Action
|
||||||
): TemplatesState =>
|
): TemplatesState =>
|
||||||
produce(state, draftState => {
|
produce(state, draftState => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ActionTypes.PopulateTemplateSummaries: {
|
case POPULATE_TEMPLATE_SUMMARIES: {
|
||||||
const {status, items} = action.payload
|
setResource<TemplateSummary>(draftState, action, ResourceType.Templates)
|
||||||
draftState.status = status
|
|
||||||
if (items) {
|
|
||||||
draftState.items = items
|
|
||||||
} else {
|
|
||||||
draftState.items = null
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionTypes.SetTemplatesStatus: {
|
case SET_TEMPLATES_STATUS: {
|
||||||
const {status} = action.payload
|
const {status} = action
|
||||||
draftState.status = status
|
draftState.status = status
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionTypes.SetTemplateSummary: {
|
case SET_TEMPLATE_SUMMARY: {
|
||||||
const updated = draftState.items.map(t => {
|
setResourceAtID<TemplateSummary>(
|
||||||
if (t.id === action.payload.id) {
|
draftState,
|
||||||
return action.payload.templateSummary
|
action,
|
||||||
}
|
ResourceType.Templates
|
||||||
|
)
|
||||||
return t
|
|
||||||
})
|
|
||||||
|
|
||||||
draftState.items = updated
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionTypes.SetExportTemplate: {
|
case SET_EXPORT_TEMPLATE: {
|
||||||
const {status, item} = action.payload
|
const {status, item} = action
|
||||||
draftState.exportTemplate.status = status
|
draftState.exportTemplate.status = status
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
|
@ -67,21 +71,14 @@ export const templatesReducer = (
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionTypes.RemoveTemplateSummary: {
|
case REMOVE_TEMPLATE_SUMMARY: {
|
||||||
const {templateID} = action.payload
|
removeResource<TemplateSummary>(draftState, action)
|
||||||
const {items} = draftState
|
|
||||||
draftState.items = items.filter(l => {
|
|
||||||
return l.id !== templateID
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionTypes.AddTemplateSummary: {
|
case ADD_TEMPLATE_SUMMARY: {
|
||||||
const {item} = action.payload
|
addResource<TemplateSummary>(draftState, action, ResourceType.Templates)
|
||||||
const {items} = draftState
|
|
||||||
|
|
||||||
draftState.items = [...items, item]
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import {
|
import {
|
||||||
Cell,
|
|
||||||
Bucket,
|
|
||||||
Dashboard,
|
|
||||||
Authorization,
|
Authorization,
|
||||||
Organization,
|
Bucket,
|
||||||
|
Cell,
|
||||||
|
Dashboard,
|
||||||
Member,
|
Member,
|
||||||
|
Organization,
|
||||||
RemoteDataState,
|
RemoteDataState,
|
||||||
Telegraf,
|
|
||||||
Scraper,
|
Scraper,
|
||||||
View,
|
View,
|
||||||
TasksState,
|
TasksState,
|
||||||
|
Telegraf,
|
||||||
|
TemplatesState,
|
||||||
VariablesState,
|
VariablesState,
|
||||||
} from 'src/types'
|
} from 'src/types'
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ export interface ResourceState {
|
||||||
[ResourceType.Scrapers]: NormalizedState<Scraper>
|
[ResourceType.Scrapers]: NormalizedState<Scraper>
|
||||||
[ResourceType.Tasks]: TasksState
|
[ResourceType.Tasks]: TasksState
|
||||||
[ResourceType.Telegrafs]: TelegrafsState
|
[ResourceType.Telegrafs]: TelegrafsState
|
||||||
|
[ResourceType.Templates]: TemplatesState
|
||||||
[ResourceType.Variables]: VariablesState
|
[ResourceType.Variables]: VariablesState
|
||||||
[ResourceType.Views]: NormalizedState<View>
|
[ResourceType.Views]: NormalizedState<View>
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
Scraper,
|
Scraper,
|
||||||
Task,
|
Task,
|
||||||
Telegraf,
|
Telegraf,
|
||||||
|
TemplateSummary,
|
||||||
Variable,
|
Variable,
|
||||||
View,
|
View,
|
||||||
} from 'src/types'
|
} from 'src/types'
|
||||||
|
@ -88,6 +89,14 @@ export interface TaskEntities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TemplateSummaryEntities defines the result of normalizr's normalization
|
||||||
|
// of the "templates resource"
|
||||||
|
export interface TemplateSummaryEntities {
|
||||||
|
templates: {
|
||||||
|
[uuid: string]: TemplateSummary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VariableEntities defines the result of normalizr's normalization
|
// VariableEntities defines the result of normalizr's normalization
|
||||||
// of the "variables" resource
|
// of the "variables" resource
|
||||||
export interface VariableEntities {
|
export interface VariableEntities {
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
TelegrafEditorActivePluginState,
|
TelegrafEditorActivePluginState,
|
||||||
TelegrafEditorState,
|
TelegrafEditorState,
|
||||||
} from 'src/dataLoaders/reducers/telegrafEditor'
|
} from 'src/dataLoaders/reducers/telegrafEditor'
|
||||||
import {TemplatesState} from 'src/templates/reducers'
|
|
||||||
import {RangeState} from 'src/dashboards/reducers/ranges'
|
import {RangeState} from 'src/dashboards/reducers/ranges'
|
||||||
import {UserSettingsState} from 'src/userSettings/reducers'
|
import {UserSettingsState} from 'src/userSettings/reducers'
|
||||||
import {OverlayState} from 'src/overlays/reducers/overlays'
|
import {OverlayState} from 'src/overlays/reducers/overlays'
|
||||||
|
@ -53,7 +52,6 @@ export interface AppState {
|
||||||
telegrafEditorActivePlugins: TelegrafEditorActivePluginState
|
telegrafEditorActivePlugins: TelegrafEditorActivePluginState
|
||||||
plugins: PluginResourceState
|
plugins: PluginResourceState
|
||||||
telegrafEditor: TelegrafEditorState
|
telegrafEditor: TelegrafEditorState
|
||||||
templates: TemplatesState
|
|
||||||
timeMachines: TimeMachinesState
|
timeMachines: TimeMachinesState
|
||||||
timeRange: TimeRange
|
timeRange: TimeRange
|
||||||
userSettings: UserSettingsState
|
userSettings: UserSettingsState
|
||||||
|
|
|
@ -1,10 +1,28 @@
|
||||||
import {
|
import {
|
||||||
ILabel,
|
|
||||||
DocumentListEntry,
|
|
||||||
Document,
|
Document,
|
||||||
|
DocumentCreate,
|
||||||
|
DocumentListEntry,
|
||||||
DocumentMeta,
|
DocumentMeta,
|
||||||
|
ILabel,
|
||||||
} from '@influxdata/influx'
|
} from '@influxdata/influx'
|
||||||
import {Dashboard, View, Cell, Label, Variable} from 'src/types'
|
import {
|
||||||
|
Cell,
|
||||||
|
Dashboard,
|
||||||
|
Label,
|
||||||
|
NormalizedState,
|
||||||
|
RemoteDataState,
|
||||||
|
Variable,
|
||||||
|
View,
|
||||||
|
} from 'src/types'
|
||||||
|
|
||||||
|
export interface TemplateSummary extends DocumentListEntry {
|
||||||
|
labels: ILabel[]
|
||||||
|
status: RemoteDataState
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TemplatesState extends NormalizedState<TemplateSummary> {
|
||||||
|
exportTemplate: {status: RemoteDataState; item: DocumentCreate}
|
||||||
|
}
|
||||||
|
|
||||||
export enum TemplateType {
|
export enum TemplateType {
|
||||||
Label = 'label',
|
Label = 'label',
|
||||||
|
@ -168,7 +186,3 @@ export interface VariableTemplate extends TemplateBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Template = TaskTemplate | DashboardTemplate | VariableTemplate
|
export type Template = TaskTemplate | DashboardTemplate | VariableTemplate
|
||||||
|
|
||||||
export interface TemplateSummary extends DocumentListEntry {
|
|
||||||
labels: ILabel[]
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {normalize} from 'normalizr'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {notify} from 'src/shared/actions/notifications'
|
import {notify} from 'src/shared/actions/notifications'
|
||||||
import {setExportTemplate} from 'src/templates/actions'
|
import {setExportTemplate} from 'src/templates/actions/creators'
|
||||||
import {
|
import {
|
||||||
setValues,
|
setValues,
|
||||||
setVariables,
|
setVariables,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import ExportOverlay from 'src/shared/components/ExportOverlay'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import {convertToTemplate as convertToTemplateAction} from 'src/variables/actions/thunks'
|
import {convertToTemplate as convertToTemplateAction} from 'src/variables/actions/thunks'
|
||||||
import {clearExportTemplate as clearExportTemplateAction} from 'src/templates/actions'
|
import {clearExportTemplate as clearExportTemplateAction} from 'src/templates/actions/thunks'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {AppState} from 'src/types'
|
import {AppState} from 'src/types'
|
||||||
|
@ -62,8 +62,8 @@ class VariableExportOverlay extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstp = (state: AppState): StateProps => ({
|
const mstp = (state: AppState): StateProps => ({
|
||||||
variableTemplate: state.templates.exportTemplate.item,
|
variableTemplate: state.resources.templates.exportTemplate.item,
|
||||||
status: state.templates.exportTemplate.status,
|
status: state.resources.templates.exportTemplate.status,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mdtp: DispatchProps = {
|
const mdtp: DispatchProps = {
|
||||||
|
|
Loading…
Reference in New Issue