diff --git a/app/src/protocol/index.js b/app/src/protocol/index.js index bffe5857165..ce2b12f1e3a 100644 --- a/app/src/protocol/index.js +++ b/app/src/protocol/index.js @@ -4,6 +4,7 @@ import path from 'path' import startCase from 'lodash/startCase' import { createSelector } from 'reselect' import { getter } from '@thi.ng/paths' +import { getProtocolSchemaVersion } from '@opentrons/shared-data' import { fileToProtocolFile, parseProtocolData, @@ -101,22 +102,45 @@ type NumberGetter = (?ProtocolData) => ?number type StringSelector = OutputSelector type NumberSelector = OutputSelector type ProtocolTypeSelector = OutputSelector +type ProtocolInfoSelector = OutputSelector< + State, + void, + { + protocolName: ?string, + lastModified: ?number, + appName: ?string, + appVersion: ?string, + } +> type CreatorAppSelector = OutputSelector< State, void, { name: ?string, version: ?string } > -const getName: StringGetter = getter('metadata.protocol-name') +const protocolV1V2GetterPaths = { + name: 'metadata.protocol-name', + lastModified: 'metadata.last-modified', + appName: 'designer-application.application-name', + appVersion: 'designer-application.application-version', +} + +const PROTOCOL_GETTER_PATHS_BY_SCHEMA = { + '1': protocolV1V2GetterPaths, + '2': protocolV1V2GetterPaths, + '3': { + name: 'metadata.protocolName', + lastModified: 'metadata.lastModified', + appName: 'designerApplication.name', + appVersion: 'designerApplication.version', + }, +} + const getAuthor: StringGetter = getter('metadata.author') const getDesc: StringGetter = getter('metadata.description') const getCreated: NumberGetter = getter('metadata.created') -const getLastModified: NumberGetter = getter('metadata.last-modified') const getSource: StringGetter = getter('metadata.source') -const getAppName: StringGetter = getter('designer-application.application-name') -const getAppVersion: StringGetter = getter( - 'designer-application.application-version' -) + const stripDirAndExtension = f => path.basename(f, path.extname(f)) export const getProtocolFile = (state: State) => state.protocol.file @@ -128,15 +152,50 @@ export const getProtocolFilename: StringSelector = createSelector( file => file && file.name ) -export const getProtocolLastModified: NumberSelector = createSelector( - getProtocolFile, - file => file && file.lastModified +// TODO: (ka 2019-06-11): Investigate removing this unused? selector +// export const getProtocolLastModified: NumberSelector = createSelector( +// getProtocolFile, +// file => file && file.lastModified +// ) + +export const getProtocolDisplayData: $Shape = createSelector( + getProtocolData, + getProtocolFilename, + (data, name) => { + if (!data) + return { + protocolName: name && stripDirAndExtension(name), + lastModified: null, + appName: null, + appVersion: null, + } + const version = (data && getProtocolSchemaVersion(data)) || 1 + const getName = getter(PROTOCOL_GETTER_PATHS_BY_SCHEMA[version]['name']) + const getLastModified = getter( + PROTOCOL_GETTER_PATHS_BY_SCHEMA[version]['lastModified'] + ) + const getAppName = getter( + PROTOCOL_GETTER_PATHS_BY_SCHEMA[version]['appName'] + ) + const getAppVersion = getter( + PROTOCOL_GETTER_PATHS_BY_SCHEMA[version]['appVersion'] + ) + const protocolName = getName(data) || (name && stripDirAndExtension(name)) + const lastModified = getLastModified(data) || getCreated(data) + const appName = getAppName(data) + const appVersion = getAppVersion(data) + return { + protocolName: protocolName, + lastModified: lastModified, + appName: appName, + appVersion: appVersion, + } + } ) export const getProtocolName: StringSelector = createSelector( - getProtocolFilename, - getProtocolData, - (name, data) => getName(data) || (name && stripDirAndExtension(name)) + getProtocolDisplayData, + displayData => displayData.protocolName ) export const getProtocolAuthor: StringSelector = createSelector( @@ -156,9 +215,8 @@ export const getProtocolSource: StringSelector = createSelector( export const getProtocolLastUpdated: NumberSelector = createSelector( getProtocolFile, - getProtocolData, - (file, data) => - getLastModified(data) || getCreated(data) || (file && file.lastModified) + getProtocolDisplayData, + (file, displayData) => displayData.lastModified || (file && file.lastModified) ) export const getProtocolType: ProtocolTypeSelector = createSelector( @@ -167,8 +225,13 @@ export const getProtocolType: ProtocolTypeSelector = createSelector( ) export const getProtocolCreatorApp: CreatorAppSelector = createSelector( - getProtocolData, - data => ({ name: getAppName(data), version: getAppVersion(data) }) + getProtocolDisplayData, + displayData => { + return { + name: displayData.appName, + version: displayData.appVersion, + } + } ) const METHOD_OT_API = 'Opentrons API' @@ -178,11 +241,11 @@ export const getProtocolMethod: StringSelector = createSelector( getProtocolFile, getProtocolContents, getProtocolData, - (file, contents, data) => { + getProtocolCreatorApp, + (file, contents, data, app) => { const isJson = file && fileIsJson(file) - const appName = getAppName(data) - const appVersion = getAppVersion(data) - const readableName = appName && startCase(appName) + const appVersion = app && app.version + const readableName = app && startCase(app.name) if (!file || !contents) return null if (isJson === true && !readableName) return METHOD_UNKNOWN diff --git a/app/src/protocol/protocol-data.js b/app/src/protocol/protocol-data.js index c1e887c3778..a4b6e2a3a77 100644 --- a/app/src/protocol/protocol-data.js +++ b/app/src/protocol/protocol-data.js @@ -34,6 +34,7 @@ export function parseProtocolData( } } else if (metadata) { // grab Python protocol metadata, if any + // $FlowFixMe: (ka, 2019-06-10): cant differentiate which file schema file is needed return { metadata } } diff --git a/app/src/protocol/types.js b/app/src/protocol/types.js index 0ec54871d96..f0a05451b7a 100644 --- a/app/src/protocol/types.js +++ b/app/src/protocol/types.js @@ -1,10 +1,14 @@ // @flow // protocol type defs -import type { SchemaV1ProtocolFile } from '@opentrons/shared-data' +import type { + SchemaV1ProtocolFile, + SchemaV3ProtocolFile, +} from '@opentrons/shared-data' // data may be a full JSON protocol or just a metadata dict from Python export type ProtocolData = | SchemaV1ProtocolFile<{}> + | SchemaV3ProtocolFile<{}> | { metadata: $PropertyType, 'metadata'> } // NOTE: add union of additional versions after schema is bumped diff --git a/shared-data/js/index.js b/shared-data/js/index.js index efeae739512..d623e06e73b 100644 --- a/shared-data/js/index.js +++ b/shared-data/js/index.js @@ -12,5 +12,4 @@ export * from './pipettes' export * from './types' export * from './labwareTools' export * from './modules' -export * from '../protocol/flowTypes/schemaV1' -export * from '../protocol/flowTypes/schemaV3' +export * from '../protocol' diff --git a/shared-data/protocol/index.js b/shared-data/protocol/index.js new file mode 100644 index 00000000000..1b59f446275 --- /dev/null +++ b/shared-data/protocol/index.js @@ -0,0 +1,25 @@ +// @flow +import type { SchemaV1ProtocolFile } from './flowTypes/schemaV1' +import type { SchemaV3ProtocolFile } from './flowTypes/schemaV3' + +type ProtocolData = + | $Shape> + | $Shape> + +// $FlowFixMe: (ka, 2019-06-10): cant differentiate which file schema file is needed +export function getProtocolSchemaVersion(data: ProtocolData): ?number { + if (data.schemaVersion > 3) { + console.warn('this is protocol schema version is not yet supported') + } + if (data.schemaVersion === 3) { + return 3 + } else if (data['protocol-schema'] === '2.0.0') { + return 2 + } else if (data['protocol-schema'] === '1.0.0') { + return 1 + } + return null +} + +export * from './flowTypes/schemaV1' +export * from './flowTypes/schemaV3'