NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

import React, {useEffect, Fragment, useMemo} from 'react';
import {observer} from 'mobx-react';
import get from 'lodash-es/get';
import Papa from 'papaparse';
import moment from 'moment';
import {Accordion, Card} from 'react-bootstrap';
import isEmpty from 'lodash-es/isEmpty';
import ConfirmModal from '@aosprodsys/brucke-ui-core/dist/es/components/Modal';
import Toggle from '@aosprodsys/brucke-ui-core/dist/es/components/Toggle';
import GridIcon from '@apple/symbols/medium/square.grid.3x3.fill.svg';
import Position from '@aosprodsys/brucke-ui-core/dist/es/components/Position';
import FilterTable from '@aosprodsys/brucke-ui-core/dist/es/components/filterTable/FilterTable';
import Select from '@aosprodsys/brucke-ui-core/dist/es/components/Select';
import GraphIcon from '../../icons/Graph.svg';
import {StoreContext} from '../../utils/StoreContext';
import TechSpecsGridView from './TechSpecsGridView';
import TechSpecsCollectionGraphViewWithGroupings from './TechSpecsCollectionGraphViewWithGroupings';
import TechSpecsGraphView from './TechSpecsGraphView';
import {
getTreeDataWithGroupingsWithCollections,
getTreeDataWithCollection,
getCollectionKeys,
getTreeData,
getTreeDataWithGroupings,
markTechSpecsNodes
} from './helpers/treeDataUtils';
import NavTabs from '@aosprodsys/brucke-ui-core/dist/es/components/NavTabs';
import {getNodeShape, wrapText} from './helpers/nodeShapeUtils';
import MobileViewHeader from '../sharedComponents/mobileViewHeader/MobileViewHeader';
import DebugList from '../sharedComponents/debugList/DebugList';
import MobileDebugListModal from '../sharedComponents/debugList/MobileDebugListModal';
import Header from '../../components/Header';
import {decode} from '../utils/helpers';
import downloadFile from '../../utils/downloadFile';
import Constants from '../../../client/constants/AppConstants';
import {useScreen} from '../utils/screen';
import SidebarModal from '../sharedComponents/debugList/SidebarModal';

import styles from './sass/tech-specs-prototype-collection-schema.scss';

function TechSpecsPrototypeCollectionSchema({location, history}) {
const table = React.useRef(null);
const {techspecCollectionSchema, appState} = React.useContext(StoreContext);
const {isInitializing} = appState;
const {
configureForm,
optionValuesWithFacetsSummary,
displayGrid,
detailLists,
optionValuesMap,
sortTemplateMap,
optionGroupDimensions,
optionGroupVariantValues,
optionGroupAttributesMap,
isTechSpecModalOpen,
selectedTechSpecType,
selectedNode,
graphViewType,
graphViewInitialDepth,
depthGraphViewDropdownOptions,
graphViewPart,
graphViewPartOptions,
CollectionSchemaParts,
collectionSchema,
showDebugView,
debugList,
displayName,
specData,
techSpecSchema,
isOptionGroupDetailModalOpen,
selectedOptionGroup,
showQueryPanel,
showGraphViewWithGroupings
} = techspecCollectionSchema;
const query = location?.query;
const {isMobile} = useScreen();
const handleQueryToggle = () =>
techspecCollectionSchema.updateValue({
key: 'showQueryPanel',
value: !showQueryPanel
});
const exportConfig = {
displayName: `_Exported_Tech_Specs_Collection_Schema_${displayName
?.replace('Customize your ', '')
.replaceAll(' ', '_')}`
};

const graphViewDropdownOptions = [{label: 'Vertical', value: 'vertical'}, {label: 'Horizontal', value: 'horizontal'}];
const groups = optionValuesWithFacetsSummary
.filter(grp => {
return !isEmpty(grp.variantValuesSummaryByVariantKey);
})
.sort((x, y) => Number(x.sortOrder) - Number(y.sortOrder));

useEffect(
() => {
if (query.collectionSchema !== undefined) {
techspecCollectionSchema.updateValue({key: 'collectionSchema', value: query.collectionSchema === 'true'});
}

if (query.techSpecSchema !== undefined) {
techspecCollectionSchema.updateValue({key: 'techSpecSchema', value: query.techSpecSchema === 'true'});
}

if (query.part) {
const splittedpartOptions = query?.part?.split(',');
const partOptions = [];
if (splittedpartOptions?.length > 1) {
partOptions.push({
label: 'All',
value: query.part
});
splittedpartOptions?.forEach(option => {
partOptions.push({
label: option,
value: option
});
});
} else {
partOptions.push({
label: query.part,
value: query.part
});
}

techspecCollectionSchema.updateValue({key: 'graphViewPartOptions', value: partOptions});
techspecCollectionSchema.updateValue({
key: 'graphViewPart',
value: decode(query.part)
.map(part => part.label)
.join(', ')
});
}
},
[query]
);

const appliedVariantFilters = useMemo(
() => {
const filters = [];
configureForm?.steps?.forEach(page => {
page.forEach(coll => {
coll.variants?.forEach(([ogt, variantKey, variantValue]) => {
if (ogt && variantValue?.label) {
filters.push(`${ogt}:${variantKey?.label || ''}:${variantValue.label}`);
}
});
});
});
return filters;
},
[configureForm]
);

const treeData = useMemo(
() => {
if (!specData?.length) return {name: graphViewPart, childern: []};
return showGraphViewWithGroupings
? getTreeDataWithGroupings(specData, graphViewPart)
: getTreeData(specData, graphViewPart);
},
[specData, graphViewType, showGraphViewWithGroupings]
);

const treeDataWithCollection = useMemo(
() => {
const raw = showGraphViewWithGroupings
? getTreeDataWithGroupingsWithCollections(optionValuesWithFacetsSummary, graphViewPart, specData)
: getTreeDataWithCollection(optionValuesWithFacetsSummary, graphViewPart, specData);
const collectionKeys = getCollectionKeys(optionValuesWithFacetsSummary);
return markTechSpecsNodes(raw, collectionKeys);
},
[optionValuesWithFacetsSummary, specData, graphViewType, showGraphViewWithGroupings]
);

const reFetchDisplayView = part => {
const requestQuery = {
part,
revision: query.revision,
segment: query.segment,
geo: query.geo,
language: query.language,
channel: query.channel
};
techspecCollectionSchema.fetchDisplayView(requestQuery);
};

const title = 'Tech Specs Collection Schema';

const tableActionRenderer = rowCount => (
<div>
<div className="right-container">
<button
className="global-link-bold link"
onClick={() => {
const columns = get(table.current, 'props.columns', []);
const rows = selectedOptionGroup.optionValueToVariants;
const exportRows = rows.map(item => {
const rowObj = {};
columns.forEach(col => {
if (item.variantKeyToValue && col.accessor in item.variantKeyToValue) {
rowObj[col.Header] = item.variantKeyToValue[col.accessor] ?? '';
} else if (typeof col.accessor === 'function') {
rowObj[col.Header] = col.accessor(item);
} else {
rowObj[col.Header] = get(item, col.accessor, '');
}
});
return rowObj;
});
downloadFile(
`${moment(new Date()).format(Constants.EXPORT_DATE_FORMAT)}_Exported_Collection_Schema${
rows.length === exportRows.length ? '' : '_filtered'
}.csv`,
'text/csv',
Papa.unparse({
fields: columns.map(c => c.Header),
data: exportRows
})
);
}}
>
Export Table
</button>
<div className="global-body">{rowCount} Rows</div>
</div>
</div>
);

const accordionBody = (
<ul className="params-list">
<li>
<span className="global-header-medium">Schema Type:</span>
<span className="global-body-medium">{techSpecSchema ? 'TechSpecs Schema' : 'Collection Schema'}</span>
</li>
<li>
<span className="global-header-medium">Revision:</span>
<span className="global-body-medium">{configureForm.revision?.label}</span>
</li>
<li>
<span className="global-header-medium">Collection Id:</span>
<span className="global-body-medium">
{configureForm.steps
?.flatMap(page => page)
.map(coll => coll.aosContainerParts?.map(p => p.label).join(', '))
.filter(Boolean)
.join(', ')}
</span>
</li>
<li className="steps">
<div>
<span className="global-header-medium">Option Group Type & Variants:</span>
{configureForm.steps?.map((pages, pageIdx) => (
<div className="page" key={pageIdx}>
{pages.map((coll, collIdx) => (
<div className="collection" key={collIdx}>
<div className="step">
{coll.variants?.map((item, idx) => {
const [ogt, variantKey, variantValue, meta] = item;
return (
<div key={`primary-group-${idx}`}>
<div className="ogt">{ogt && <span className="global-header-medium">{ogt}</span>}</div>
{variantKey && (
<div className="variant-key global-body-medium">
{Array.isArray(variantKey) ? variantKey.map(v => v.label).join(', ') : variantKey.label}
</div>
)}
{variantValue && (
<div className="variant-value global-body-medium">
{Array.isArray(variantValue)
? variantValue.map(v => v.label).join(', ')
: variantValue.label}
</div>
)}
<div className="variant-children">
{meta?.variants?.map((child, cIdx) => {
const [subOgt, subVariants] = child;
return (
<div key={`sub-group-${idx}-${cIdx}`}>
<span className="global-header-medium">{subOgt}</span>
{Array.isArray(subVariants) &&
subVariants.map((res, sIdx) => (
<div key={`sub-variant-${idx}-${cIdx}-${sIdx}`} className="global-body-medium">
{res.label}
</div>
))}
</div>
);
})}
</div>
</div>
);
})}
</div>
</div>
))}
</div>
))}
</div>
</li>
<li>
<span className="global-header-medium">Marketing Context:</span>
<span className="global-body-medium">
{configureForm.channel} - {configureForm.geo} - {configureForm.language} - {configureForm.segment}
</span>
</li>
</ul>
);
const newTest = () => {
techspecCollectionSchema.reset();
history.push({pathname: '/tech-specs-collection-schema', search: ''});
};

const collectionSchemaView = !displayGrid && !isEmpty(selectedNode) && !!collectionSchema;
const StatValue = ({specVariant}) => {
return (
<figure class="stat stat-reduced stat-center">
<div class="stat-content">
<span class="stat-value">{specVariant.specValue}</span>
<span class="stat-caption">{specVariant.specKey}</span>
</div>
</figure>
);
};

return (
<Fragment>
{isMobile ? (
<MobileViewHeader
title={title}
middleRenderer={() => {
return (
<ul className="params-list">
<li>
<button className="link" onClick={newTest} disabled={isInitializing}>
New Test
</button>
</li>
<li>
<MobileDebugListModal debugList={debugList} exportConfig={exportConfig} />
</li>
<li>
<Accordion className="parameters-accordion" data-testid="accordion">
<Card>
<Card.Header>
<Accordion.Toggle className="parameters-toggler" variant="link" eventKey="0">
<span
className={`global-link-bold-gray icon icon-after icon-chevron${
showQueryPanel ? 'up' : 'down'
}`}
onClick={handleQueryToggle}
>
{showQueryPanel ? 'Hide Parameters' : 'Show Parameters'}
</span>
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0" data-testid="accordion-body">
<Card.Body>{accordionBody}</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</li>
</ul>
);
}}
/>
) : (
<Header
title={title}
middleRenderer={() => {
return (
<Accordion data-testid="accordion">
<Card>
<Accordion.Collapse eventKey="0" data-testid="accordion-body">
<Card.Body>{accordionBody}</Card.Body>
</Accordion.Collapse>
<Card.Header>
<Accordion.Toggle variant="link" eventKey="0">
<div className="header-container">
<a className="panel-toggler global-link-bold-gray" onClick={handleQueryToggle}>
<div>{showQueryPanel ? 'Close Parameters' : 'View Parameters'}</div>
<i className={`icon icon-chevron${showQueryPanel ? 'up' : 'down'}`} />
</a>
</div>
</Accordion.Toggle>
</Card.Header>
</Card>
</Accordion>
);
}}
>
<button
className="button button-block"
onClick={() => {
techspecCollectionSchema.updateValue({key: 'showDebugView', value: !showDebugView});
}}
>
View API Calls
</button>
<button
disabled={isInitializing}
className="button button-block button-neutral"
onClick={() => {
techspecCollectionSchema.reset();
history.push({pathname: '/tech-specs-collection-schema', search: ''});
}}
>
New Test
</button>
</Header>
)}
<div className={`${styles.page}`}>
{isInitializing ? (
<div className="loader" />
) : (
<>
<h1 className={`header-label ${collectionSchemaView ? 'expanded-graph-container' : ''}`}>{displayName}</h1>
<div className={`expanded-label-container ${collectionSchemaView ? 'expanded-graph-container' : ''}`}>
<div className="graph-view-depth-node-dropdown">
{!displayGrid && specData.length ? (
<Fragment>
<Select
placeholder={'Graph View Level'}
value={graphViewInitialDepth}
options={depthGraphViewDropdownOptions}
onChange={e => {
techspecCollectionSchema.updateValue({
key: 'graphViewInitialDepth',
value: Number(e.target.value)
});
}}
/>
<Select
placeholder={'Graph View Type'}
value={graphViewType}
options={graphViewDropdownOptions}
onChange={e => {
techspecCollectionSchema.updateValue({key: 'graphViewType', value: e.target.value});
}}
/>
<Toggle
{...{
className: 'show-default-options-toggle',
inputProps: {
checked: showGraphViewWithGroupings,
onChange: () => {
if (showGraphViewWithGroupings) {
techspecCollectionSchema.updateValue({key: 'showGraphViewWithGroupings', value: false});
} else {
techspecCollectionSchema.updateValue({key: 'showGraphViewWithGroupings', value: true});
}
}
},
label: 'Show TechSpec Variants'
}}
/>
</Fragment>
) : null}
</div>

<div className="expanded-label">
<div className="graph-part-dropdown">
{!displayGrid &&
graphViewPartOptions?.length > 1 && (
<Select
placeholder={'Selected Part'}
value={graphViewPart}
options={graphViewPartOptions}
onChange={e => {
techspecCollectionSchema.updateValue({key: 'graphViewPart', value: e.target.value});
reFetchDisplayView(e.target.value);
}}
/>
)}
</div>
<button
className={`view-select-button ${displayGrid ? 'active' : ''}`}
onClick={() => {
techspecCollectionSchema.updateValue({key: 'displayGrid', value: true});
techspecCollectionSchema.updateValue({key: 'isTechSpecModalOpen', value: false});
}}
>
<div className={`label ${displayGrid ? 'active' : ''}`}>
<GridIcon className="apple-icons" layoutMode="glyphBox" desiredFontSize={15} />
Grid View
</div>
</button>
<button
className={`view-select-button ${!displayGrid ? 'active' : ''}`}
onClick={() => {
techspecCollectionSchema.updateValue({key: 'displayGrid', value: false});
}}
>
<div className={`label ${!displayGrid ? 'active' : ''}`}>
<img src={GraphIcon} className="graph-icon" />
Graph View
</div>
</button>
</div>
</div>
{!displayGrid &&
appliedVariantFilters.length > 0 && (
<div className="applied-filters-container">
<span className="customizations-label">Customizations:</span>
<div className="filters-list">
{appliedVariantFilters.map((filter, idx) => (
<div key={idx} className="filter-wrapper">
{filter}
</div>
))}
</div>
</div>
)}
{specData?.length ? (
displayGrid ? (
<TechSpecsGridView
groups={specData}
onOptionGroupTypeClick={grp => {
techspecCollectionSchema.updateValue({key: 'selectedTechSpecType', value: grp});
techspecCollectionSchema.updateValue({key: 'isTechSpecModalOpen', value: true});
}}
/>
) : (
<>
{collectionSchema ? (
<TechSpecsCollectionGraphViewWithGroupings
groups={groups}
techSpecs={specData}
optionValuesWithFacetsSummary={optionValuesWithFacetsSummary}
optionValuesMap={optionValuesMap}
sortTemplateMap={sortTemplateMap}
detailLists={detailLists}
withGroupings={showGraphViewWithGroupings}
graphViewType={graphViewType}
part={graphViewPart}
query={query}
optionGroupDimensions={optionGroupDimensions}
optionGroupVariantValues={optionGroupVariantValues}
optionGroupAttributesMap={optionGroupAttributesMap}
selectedNode={selectedNode}
CollectionSchemaParts={CollectionSchemaParts}
setSelectedNode={selectedNode => {
techspecCollectionSchema.updateValue({key: 'selectedNode', value: selectedNode});
}}
graphViewInitialDepth={graphViewInitialDepth}
setDepthGraphViewDropdownOptions={optionsData => {
techspecCollectionSchema.updateValue({
key: 'depthGraphViewDropdownOptions',
value: optionsData
});
}}
onOptionGroupTypeClick={grp => {
techspecCollectionSchema.updateValue({key: 'selectedOptionGroup', value: grp});
techspecCollectionSchema.updateValue({key: 'isOptionGroupDetailModalOpen', value: true});
}}
onTechSpecsClick={grp => {
techspecCollectionSchema.updateValue({key: 'selectedTechSpecType', value: grp});
techspecCollectionSchema.updateValue({key: 'isTechSpecModalOpen', value: true});
}}
treeData={treeDataWithCollection}
wrapText={wrapText}
getNodeShape={getNodeShape}
/>
) : (
<TechSpecsGraphView
groups={specData}
optionValuesWithFacetsSummary={optionValuesWithFacetsSummary}
optionValuesMap={optionValuesMap}
withGroupings={showGraphViewWithGroupings}
graphViewType={graphViewType}
sortTemplateMap={sortTemplateMap}
detailLists={detailLists}
part={graphViewPart}
query={query}
optionGroupDimensions={optionGroupDimensions}
optionGroupVariantValues={optionGroupVariantValues}
optionGroupAttributesMap={optionGroupAttributesMap}
selectedNode={selectedNode}
CollectionSchemaParts={CollectionSchemaParts}
setSelectedNode={selectedNode => {
techspecCollectionSchema.updateValue({key: 'selectedNode', value: selectedNode});
}}
graphViewInitialDepth={graphViewInitialDepth}
setDepthGraphViewDropdownOptions={optionsData => {
techspecCollectionSchema.updateValue({
key: 'depthGraphViewDropdownOptions',
value: optionsData
});
}}
onOptionGroupTypeClick={grp => {
techspecCollectionSchema.updateValue({key: 'selectedTechSpecType', value: grp});
techspecCollectionSchema.updateValue({key: 'isTechSpecModalOpen', value: true});
}}
treeData={treeData}
getNodeShape={getNodeShape}
wrapText={wrapText}
/>
)}
</>
)
) : (
<h4>No Results.</h4>
)}
{isMobile ? null : (
<SidebarModal
className={styles.sidebarModal}
show={showDebugView}
title="API Calls"
onHide={() => {
techspecCollectionSchema.updateValue({key: 'showDebugView', value: false});
}}
>
<DebugList debugList={debugList} exportConfig={exportConfig} defaultShow={true} hideToggle={true} />
</SidebarModal>
)}
<ConfirmModal
{...{
show: isTechSpecModalOpen,
onHide: () =>
techspecCollectionSchema.updateValue({
key: 'isTechSpecModalOpen',
value: false
}),
onConfirm: () =>
techspecCollectionSchema.updateValue({
key: 'isTechSpecModalOpen',
value: false
}),
confirmButtonText: 'Close',
showCancelButton: false
}}
>
{selectedTechSpecType ? (
<>
<h2>{selectedTechSpecType.specLabel}</h2>
<hr />
<NavTabs
navs={[
{ label: 'Tech Specs', value: 'Tech Specs' },
{ label: 'Compare', value: 'Compare' }
]}
active={'Tech Specs'}
onClick={(evt, val) => {
console.log(evt, val)
// this.props.history.push({
// pathname: '/tmall-roc-registration',
// search: queryString.stringify({tab: val})
// });
}}
/>
{'Tech Specs' ? (<div className={styles.techSpecsmodal}>
{selectedTechSpecType.specId === 'built_in_apps' ? (
<div className="ts-apps-grid">
{selectedTechSpecType.specInfo.flatMap(v =>
(v.specData || []).map((item, idx) => (
<div key={idx} className="ts-app">
{item.specText}
</div>
))
)}
</div>
) : selectedTechSpecType.specInfo.some(v => v.specVariantsGroup?.length) ? (
<div className="ts-scroll">
<table className="ts-table">
<thead>
<tr>
{selectedTechSpecType.specInfo.map((variantGroup, idx) => {
const context = variantGroup.specVariantsGroup || [];
return (
<th key={idx}>
{context.length > 0 ? context.map(v => v.variantValue).join(', ') : ''}
</th>
);
})}
</tr>
</thead>
<tbody>
{(() => {
const maxRows = Math.max(
...selectedTechSpecType.specInfo.map(v => v.specData?.length || 0)
);
return Array.from({length: maxRows}).map((_, rowIdx) => (
<tr key={rowIdx}>
{selectedTechSpecType.specInfo.map((variantGroup, colIdx) => {
const item = variantGroup.specData?.[rowIdx];
return <td key={colIdx}>{item ? item.specText : ''}</td>;
})}
</tr>
));
})()}
</tbody>
</table>
</div>
) : (
<div className="ts-single">
{selectedTechSpecType.specInfo.flatMap(v =>
(v.specData || []).map((item, idx) => (
<p key={idx} className="ts-item">
{item.specText}
</p>
))
)}
</div>
)}
</div>):(<> <section className="display-stats-container">
<table className="display-stats-table">
<tbody>
{(
optionGroupSpecTypes

).map(item => {
const specVariantsSet = new Set(filters[item.value]);
const specLeft = optionGroupSpecMap.left[item.value];
const renderStatValues = spec => {
return (
<div key={spec.specId} className="stat-values">
{spec.specInfo.map((specInfo, idx) => {
const specVariantsList = specVariantsSet.size
? specInfo.specData.flatMap(specData => {
return specData.specVariants.filter(specVariant =>
specVariantsSet.has(specVariant.specKey)
);
})
: specInfo.specData.flatMap(specData => specData.specVariants);

return (
<div key={`stat-values-group-${idx}`} className="stat-values-group">
{specVariantsList.map(specVariant => {
return (
<StatValue
key={`stat-value-$${specVariant.specKey}:${specVariant.specValue}`}
specVariant={specVariant}
/>
);
})}
</div>
);
})}
</div>
);
};
return (
<tr key={item.value}>
<td className="left-spec">
<div className="spec">
<h2>{item.label}</h2>
{specLeft ? renderStatValues(specLeft) : null}
</div>
</td>
</tr>
);
})}
</tbody>
</table>
</section></>)}

</>
) : null}
</ConfirmModal>

<ConfirmModal
{...{
className: styles.optionGroupDetailModal,
show: isOptionGroupDetailModalOpen,
onHide: () => techspecCollectionSchema.updateValue({key: 'isOptionGroupDetailModalOpen', value: false}),
onConfirm: () =>
techspecCollectionSchema.updateValue({key: 'isOptionGroupDetailModalOpen', value: false}),
confirmButtonText: 'Close',
showCancelButton: false
}}
>
{selectedOptionGroup ? (
<>
<div className="action-row">
<h2>{selectedOptionGroup.optionGroupType}</h2>
</div>
<Position enableTimer={false} debounceTimeout={750}>
{({width}) => {
return (
<FilterTable
ref={table}
rowCountRenderer={tableActionRenderer}
height={450}
width={Math.max(1700, width)}
columns={[
{
Header: 'OptionValue Number',
accessor: 'optionValue',
minWidth: 160
},
{
Header: 'OptionValue Name',
accessor: 'optionValueDisplayName',
minWidth: 200
},
...Object.keys(selectedOptionGroup.variantValuesSummaryByVariantKey).map(
(key, columnIndex) => ({
Header: key,
accessor: key,
id: `${key}_${columnIndex}`,
minWidth: 50,
sortMethod: (a, b, sort) => {
const aStr = a.variantKeyToValue[key] ?? '';
const bStr = b.variantKeyToValue[key] ?? '';
const comparision = aStr > bStr ? 1 : -1;
return sort === 'DESC' ? -comparision : comparision;
},
Cell: ({value, row}) => {
return <span>{row.variantKeyToValue[key]}</span>;
},
filterType: 'discrete',
filterMethod: (filter, rowData) => {
const {value} = filter;
if (!filter.value || filter.value === '') return true;
return rowData.variantKeyToValue[key] === value;
},
filterAdditionalProps: {
discreteSpecificValues: selectedOptionGroup.variantValuesSummaryByVariantKey[key],
isDisabled: () => false,
discreteSpecificCheckboxDisabled: false,
availableDiscreteOptions: selectedOptionGroup.variantValuesSummaryByVariantKey[
key
].reduce((acc, val) => {
acc[val] = true;
return acc;
}, {})
}
})
),
{
Header: 'SapPartNumbers',
accessor: 'sapPartNumbers',
minWidth: 270,
Cell: ({value}) => {
return <span>{value}</span>;
}
}
]}
data={selectedOptionGroup.optionValueToVariants}
enableGlobalFilter
showNoResultsEmptyTable
infiniteScroll
/>
);
}}
</Position>
</>
) : null}
</ConfirmModal>
</>
)}
</div>
</Fragment>
);
}

export default observer(TechSpecsPrototypeCollectionSchema);
     
 
what is notes.io
 

Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 14 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.