From 67829a2b7cf9a2d3f3ec7da444a4ca63e8eed28b Mon Sep 17 00:00:00 2001 From: Timmy Luong Date: Thu, 23 Jan 2020 22:21:06 -0800 Subject: [PATCH] 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 comments --- ui/src/dashboards/actions/thunks.ts | 2 +- .../components/DashboardExportOverlay.tsx | 6 +- ui/src/resources/components/GetResources.tsx | 2 +- ui/src/resources/selectors/getAll.ts | 9 + .../resources/selectors/getResourcesStatus.ts | 13 +- ui/src/schemas/index.ts | 14 +- ui/src/shared/components/ExportOverlay.tsx | 2 +- ui/src/shared/utils/formatStatValue.ts | 2 +- ui/src/store/configureStore.ts | 2 +- ui/src/tasks/actions/thunks.ts | 2 +- ui/src/tasks/components/TaskExportOverlay.tsx | 6 +- .../TaskImportFromTemplateOverlay.tsx | 13 +- ui/src/templates/actions/creators.ts | 75 ++++++ .../templates/actions/{index.ts => thunks.ts} | 235 +++++++----------- .../components/StaticTemplateCard.tsx | 2 +- ui/src/templates/components/TemplateCard.tsx | 5 +- .../components/TemplateExportOverlay.tsx | 6 +- .../components/TemplateImportOverlay.tsx | 12 +- .../components/TemplateViewOverlay.tsx | 6 +- ui/src/templates/components/TemplatesList.tsx | 2 +- ui/src/templates/components/TemplatesPage.tsx | 15 +- .../CreateFromTemplateOverlay.tsx | 15 +- ui/src/templates/reducers/index.test.ts | 141 ++++++++--- ui/src/templates/reducers/index.ts | 85 +++---- ui/src/types/resources.ts | 12 +- ui/src/types/schemas.ts | 9 + ui/src/types/stores.ts | 2 - ui/src/types/templates.ts | 28 ++- ui/src/variables/actions/thunks.ts | 2 +- .../components/VariableExportOverlay.tsx | 6 +- 30 files changed, 443 insertions(+), 288 deletions(-) create mode 100644 ui/src/resources/selectors/getAll.ts create mode 100644 ui/src/templates/actions/creators.ts rename ui/src/templates/actions/{index.ts => thunks.ts} (55%) diff --git a/ui/src/dashboards/actions/thunks.ts b/ui/src/dashboards/actions/thunks.ts index b77e37ac3c..f3b48e9a18 100644 --- a/ui/src/dashboards/actions/thunks.ts +++ b/ui/src/dashboards/actions/thunks.ts @@ -24,7 +24,7 @@ import { import {setViews} from 'src/views/actions/creators' import {selectValue} from 'src/variables/actions/creators' 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 {updateViewAndVariables} from 'src/views/actions/thunks' import * as creators from 'src/dashboards/actions/creators' diff --git a/ui/src/dashboards/components/DashboardExportOverlay.tsx b/ui/src/dashboards/components/DashboardExportOverlay.tsx index 162608d0de..dc7a56dd98 100644 --- a/ui/src/dashboards/components/DashboardExportOverlay.tsx +++ b/ui/src/dashboards/components/DashboardExportOverlay.tsx @@ -7,7 +7,7 @@ import ExportOverlay from 'src/shared/components/ExportOverlay' // Actions 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 import {DocumentCreate} from '@influxdata/influx' @@ -62,8 +62,8 @@ class DashboardExportOverlay extends PureComponent { } const mstp = (state: AppState): StateProps => ({ - dashboardTemplate: state.templates.exportTemplate.item, - status: state.templates.exportTemplate.status, + dashboardTemplate: state.resources.templates.exportTemplate.item, + status: state.resources.templates.exportTemplate.status, }) const mdtp: DispatchProps = { diff --git a/ui/src/resources/components/GetResources.tsx b/ui/src/resources/components/GetResources.tsx index 6904598651..0e3d2a9baa 100644 --- a/ui/src/resources/components/GetResources.tsx +++ b/ui/src/resources/components/GetResources.tsx @@ -15,7 +15,7 @@ import {getPlugins} from 'src/dataLoaders/actions/telegrafEditor' import {getScrapers} from 'src/scrapers/actions/thunks' import {getTasks} from 'src/tasks/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' // Types diff --git a/ui/src/resources/selectors/getAll.ts b/ui/src/resources/selectors/getAll.ts new file mode 100644 index 0000000000..1bbdf562d5 --- /dev/null +++ b/ui/src/resources/selectors/getAll.ts @@ -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]) +} diff --git a/ui/src/resources/selectors/getResourcesStatus.ts b/ui/src/resources/selectors/getResourcesStatus.ts index dfc68b5edf..bac0eb224b 100644 --- a/ui/src/resources/selectors/getResourcesStatus.ts +++ b/ui/src/resources/selectors/getResourcesStatus.ts @@ -8,14 +8,15 @@ export const getResourcesStatus = ( const statuses = resources.map(resource => { switch (resource) { // Normalized resource statuses - case ResourceType.Members: + case ResourceType.Authorizations: case ResourceType.Buckets: - case ResourceType.Telegrafs: - case ResourceType.Tasks: - case ResourceType.Scrapers: - case ResourceType.Variables: 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 } diff --git a/ui/src/schemas/index.ts b/ui/src/schemas/index.ts index 0394242c2d..b1f7bc5007 100644 --- a/ui/src/schemas/index.ts +++ b/ui/src/schemas/index.ts @@ -5,13 +5,13 @@ import {omit} from 'lodash' // Types import { Cell, - ResourceType, - Telegraf, - Task, + Dashboard, Label, RemoteDataState, + ResourceType, + Task, + Telegraf, Variable, - Dashboard, View, } from 'src/types' import {CellsWithViewProperties} from 'src/client' @@ -176,6 +176,12 @@ export const telegraf = new schema.Entity( 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 */ // Defines the schema for the "scrapers" resource diff --git a/ui/src/shared/components/ExportOverlay.tsx b/ui/src/shared/components/ExportOverlay.tsx index 21dc00c88c..ae2ca4c159 100644 --- a/ui/src/shared/components/ExportOverlay.tsx +++ b/ui/src/shared/components/ExportOverlay.tsx @@ -14,7 +14,7 @@ import {Controlled as ReactCodeMirror} from 'react-codemirror2' import CopyButton from 'src/shared/components/CopyButton' // Actions -import {createTemplateFromResource} from 'src/templates/actions/' +import {createTemplateFromResource} from 'src/templates/actions/thunks' // Utils import {downloadTextFile} from 'src/shared/utils/download' diff --git a/ui/src/shared/utils/formatStatValue.ts b/ui/src/shared/utils/formatStatValue.ts index be948b9dc1..19e00e2235 100644 --- a/ui/src/shared/utils/formatStatValue.ts +++ b/ui/src/shared/utils/formatStatValue.ts @@ -20,7 +20,7 @@ export const formatStatValue = ( value: number | string = 0, {decimalPlaces, prefix, suffix}: FormatStatValueOptions = {} ): string => { - let localeFormattedValue // undefined, string, or number + let localeFormattedValue: undefined | string | number if (isNumber(value)) { let digits: number diff --git a/ui/src/store/configureStore.ts b/ui/src/store/configureStore.ts index ec5fc9d47c..f38c7ad1bf 100644 --- a/ui/src/store/configureStore.ts +++ b/ui/src/store/configureStore.ts @@ -75,6 +75,7 @@ export const rootReducer = combineReducers({ scrapers: scrapersReducer, tasks: tasksReducer, telegrafs: telegrafsReducer, + templates: templatesReducer, tokens: authsReducer, variables: variablesReducer, views: viewsReducer, @@ -84,7 +85,6 @@ export const rootReducer = combineReducers({ telegrafEditor: editorReducer, telegrafEditorActivePlugins: activePluginsReducer, telegrafEditorPlugins: pluginsReducer, - templates: templatesReducer, timeMachines: timeMachinesReducer, userSettings: userSettingsReducer, variableEditor: variableEditorReducer, diff --git a/ui/src/tasks/actions/thunks.ts b/ui/src/tasks/actions/thunks.ts index ccf78abd8d..ab39eb716d 100644 --- a/ui/src/tasks/actions/thunks.ts +++ b/ui/src/tasks/actions/thunks.ts @@ -11,7 +11,7 @@ import {createTaskFromTemplate as createTaskFromTemplateAJAX} from 'src/template import * as schemas from 'src/schemas' // 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 { addTask, diff --git a/ui/src/tasks/components/TaskExportOverlay.tsx b/ui/src/tasks/components/TaskExportOverlay.tsx index 91ecfb75f8..86c5be775c 100644 --- a/ui/src/tasks/components/TaskExportOverlay.tsx +++ b/ui/src/tasks/components/TaskExportOverlay.tsx @@ -7,7 +7,7 @@ import ExportOverlay from 'src/shared/components/ExportOverlay' // Actions 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 import {AppState} from 'src/types' @@ -62,8 +62,8 @@ class TaskExportOverlay extends PureComponent { } const mstp = (state: AppState): StateProps => ({ - taskTemplate: state.templates.exportTemplate.item, - status: state.templates.exportTemplate.status, + taskTemplate: state.resources.templates.exportTemplate.item, + status: state.resources.templates.exportTemplate.status, }) const mdtp: DispatchProps = { diff --git a/ui/src/tasks/components/TaskImportFromTemplateOverlay.tsx b/ui/src/tasks/components/TaskImportFromTemplateOverlay.tsx index edcf2a5b7d..879cb94ee1 100644 --- a/ui/src/tasks/components/TaskImportFromTemplateOverlay.tsx +++ b/ui/src/tasks/components/TaskImportFromTemplateOverlay.tsx @@ -17,7 +17,7 @@ import GetResources from 'src/resources/components/GetResources' // Actions import {createTaskFromTemplate as createTaskFromTemplateAction} from 'src/tasks/actions/thunks' -import {getTemplateByID} from 'src/templates/actions' +import {getTemplateByID} from 'src/templates/actions/thunks' // Types import { @@ -30,6 +30,9 @@ import { ResourceType, } from 'src/types' +// Selectors +import {getAll} from 'src/resources/selectors/getAll' + interface StateProps { templates: TemplateSummary[] 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( t => !t.meta.type || t.meta.type === TemplateType.Task ) diff --git a/ui/src/templates/actions/creators.ts b/ui/src/templates/actions/creators.ts new file mode 100644 index 0000000000..ecd9251746 --- /dev/null +++ b/ui/src/templates/actions/creators.ts @@ -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 + | ReturnType + | ReturnType + | ReturnType + | ReturnType + | ReturnType + +type TemplateSummarySchema = NormalizedSchema< + TemplateSummaryEntities, + R +> + +// Action Creators +export const addTemplateSummary = (schema: TemplateSummarySchema) => + ({ + type: ADD_TEMPLATE_SUMMARY, + schema, + } as const) + +export const populateTemplateSummaries = ( + schema: TemplateSummarySchema +) => + ({ + 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 +) => + ({ + type: SET_TEMPLATE_SUMMARY, + id, + status, + schema, + } as const) diff --git a/ui/src/templates/actions/index.ts b/ui/src/templates/actions/thunks.ts similarity index 55% rename from ui/src/templates/actions/index.ts rename to ui/src/templates/actions/thunks.ts index 5df12e4baf..2bfcd52c0c 100644 --- a/ui/src/templates/actions/index.ts +++ b/ui/src/templates/actions/thunks.ts @@ -1,136 +1,84 @@ -// Utils -import {templateToExport} from 'src/shared/utils/resourceToTemplate' +// Libraries +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' // Types -import { - TemplateSummary, - DocumentCreate, - ITaskTemplate, - TemplateType, - ITemplate, -} from '@influxdata/influx' +import {Dispatch} from 'react' +import {DocumentCreate, ITaskTemplate, TemplateType} from '@influxdata/influx' import { RemoteDataState, GetState, DashboardTemplate, VariableTemplate, Template, + TemplateSummary, + TemplateSummaryEntities, Label, } from 'src/types' -// Actions -import {notify} from 'src/shared/actions/notifications' - -// 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 +// Utils +import {templateToExport} from 'src/shared/utils/resourceToTemplate' import {getOrg} from 'src/organizations/selectors' -export enum ActionTypes { - 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', -} +type Action = TemplateAction | NotifyAction -export type Actions = - | 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) => { +export const getTemplateByID = async (id: string): Promise