Notes
Notes - notes.io |
const isDisabled = order.disabled;
const renderInlineOptionValues = (option = {}) => {
return (
<div
className={`integrated ${styles.integrated} ${
order.isGroup ? 'is-grouped-defaults' : 'is-seperated-defaults'
}`}
>
{renderHeaderLabel(grp.subOptionGroupType)}
{renderOptionValuesWithFacetsItem(grp.subOptionGroupType, false, order)}
{optionGroupType === 'processor' && (
<SelectorRadioV2
className={`${option.className ? option.className : ''} form-radio-input`}
id={option.id}
label={<strong>No, thanks</strong>}
inputProps={{
disabled: option.isChecked || option.disabled,
checked: option.isChecked,
onClick: option.onClick
}}
onClick={option.onClick}
/>
)}
</div>
);
};
const renderVariantKeys = variants => {
const renderByType = (variant, options) => {
const renderSelectorRadio = (variant, options) => {
return options.map(option => {
const isChecked = configureForm?.[optionGroupType]?.[variant] === option.value;
return (
<SelectorRadio
id={option.id}
key={option.id}
label={option.label}
inputProps={{
disabled: isChecked || option.disabled,
checked: isChecked,
onClick: () => {
addUserActionDebugList(`User Select: ${option.label}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.fetchPNPOptions(option);
}
}}
/>
);
});
};
const renderSelectorCategory = (variant, options) => {
return options.map(option => {
const isChecked = configureForm?.[optionGroupType]?.[variant] === option.value;
return (
<SelectorCategory
id={option.id}
key={option.id}
label={option.label}
inputProps={{
disabled: isChecked || option.disabled,
checked: isChecked,
onClick: () => {
addUserActionDebugList(`User Select: ${option.label}`, 'separator', 'after-load-slection');
if (selectedOptionGroupTypeToReset === 'keyboard' && variant === 'dimensionKeyBoardColor') {
pnpPrototypeCustomize.compareChanges(option);
} else {
pnpPrototypeCustomize.fetchPNPOptions(option);
}
}
}}
/>
);
});
};
const renderSelect = (variant, options) => {
const value = configureForm?.[optionGroupType]?.[variant];
return (
<Select
placeholder={optionGroupType}
value={value}
options={options}
onChange={e => {
addUserActionDebugList(`User Select: ${e.target.value}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.fetchPNPOptions({
key: optionGroupType,
value: {
[variant]: e.target.value
},
isVariantKey: true,
variantKey: variant
});
}}
/>
);
};
const renderCustomChassisSelector = (variant, options) => {
return (
<div className={`form-group ${styles.colorNav} colornav`}>
<h4>
{!configureForm?.chassis?.dimensionColor
? `Select a finish:`
: `Finish - ${configureForm.chassis.dimensionColor}`}
</h4>
<ul className="colornav-items">
{options.map((option, idx) => {
const {id, value} = option;
const color = value;
const imageUrl = swatchImageMap[value]?.imageUrl;
const isChecked = configureForm?.[optionGroupType]?.[variant] === option.value;
return (
<li
key={id}
className={`colornav-item ${
option.disabled
? 'isDisabled'
: ''
}`}
>
<input
type="radio"
name="colornav-value-images"
className="colornav-value"
id={id}
checked={isChecked}
disabled={isChecked || option.disabled}
onClick={() => {
addUserActionDebugList(`User Select: ${option.label}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.fetchPNPOptions(option);
}}
/>
<label htmlFor={id} className="colornav-link">
<img
className={`colornav-swatch colornav-swatch-${idx}`}
src={imageUrl}
onError={e => e.target.parentNode.classList.add('apply-fallback')}
/>
<span className="colornav-label-fallback">{color}</span>
</label>
</li>
);
})}
</ul>
</div>
);
};
const renderDisplayByVariantConfig = {
keyboard: {
dimensionCTOLanguage: 'select',
dimensionKeyBoardLayout: 'selector-radio'
},
chassis: {
dimensionColor: 'selector-custom-chassis'
}
};
const variantsRender = () => {
const displayType = renderDisplayByVariantConfig[optionGroupType]?.[variant];
if (!displayType) {
return (
<div className="form-group option-selector-category">{renderSelectorCategory(variant, options)}</div>
);
} else if (displayType === 'select') {
return <div className="form-group option-select">{renderSelect(variant, options)}</div>;
} else if (displayType === 'selector-radio') {
return <div className="form-group option-selector-radio">{renderSelectorRadio(variant, options)}</div>;
} else if (displayType === 'selector-custom-chassis') {
return renderCustomChassisSelector(variant, options);
}
};
return (
<>
{variantsRender()}
{options.some(option => option.renderInlineChildren) ? renderInlineOptionValues() : null}
</>
);
};
return variants.map(k => {
const valuesSummary = grp.variantsSummary.find(item => item.variantKey === k)?.valuesSummary ?? [];
const isEnabled = (variant, optionValue) => {
//console.log(optionValueToVariants,'optionValueToVariants')
return optionValueToVariants.some(item => {
const option = {
[variant]: optionValue
};
console.log(item.displayIndicator === 'ENABLED','itemdisplayIndicator');
console.log(isMatch(getVariantKeyToValue(item.variants), option),'optionnnnnnnn')
const match =
isMatch(getVariantKeyToValue(item.variants), option) &&
(!item.hasOwnProperty('displayIndicator') || item.displayIndicator === 'ENABLED');
return match;
});
};
const options = valuesSummary.map(item => {
const key = `${optionGroupType}:${k}:${item}`;
console.log(isDisabled,'isDisabled');
console.log(!isEnabled(k, item),'isEnabled')
const disabled =
isFetching ||
(selectedOptionGroupTypeToReset === optionGroupType ? false: isDisabled || !isEnabled(k, item));
return {
id: key,
key: optionGroupType,
label: item,
value: item,
isVariantKey: true,
variantKey: k,
disabled,
renderInlineChildren: order.child && grp.subOptionGroupType
};
});
return (
<div className="option-values-components" key={k}>
<h4 className="global-body-medium">
<strong>{k}</strong>
</h4>
{renderByType(k, options)}
</div>
);
});
};
const orderTarget = isParent ? order.parent : order.child;
if (orderTarget.variants.length > 0 && !order.isGroup) {
return renderVariantKeys(orderTarget.variants);
}
const optionValue = configureForm[optionGroupType];
const checkIfOptionIsParentOfChildVariant = optionValue => {
const variants = query.configureForm.variants.find(item => item[0] === optionGroupType);
const variantsList = variants[1].map(item => item.value);
const picked = variantsList.length ? pick(optionValue, variantsList) : optionValue;
const selectedPicked = variantsList.length
? pick(configureForm[optionGroupType], variantsList)
: configureForm[optionGroupType];
return isEqual(picked, selectedPicked);
};
const options = optionValueToVariants.map(item => {
const variantKeyToValue = getVariantKeyToValue(item.variants);
const value =
renderDisplayConfig[optionGroupType] === 'select' ||
(renderDisplayConfig[optionGroupType] === 'selector-custom-configuration' && optionGroupType === 'keyboard')
? JSON.stringify(variantKeyToValue)
: variantKeyToValue;
const isOptionChecked = isEqual(optionValue, value);
let priceDelta;
if (!isOptionChecked) {
const foundPriceDelta =
priceDeltas?.[optionGroupType]?.find(pd => {
return isEqual(pd.variant, item.variants);
}) ||
priceKit.find(pk => {
return isEqual(pk.variant, item.variants);
});
if (foundPriceDelta) {
if (foundPriceDelta.lowestPrice) {
priceDelta = `From ${foundPriceDelta.lowestPrice}`;
} else if (foundPriceDelta.priceDeltaDisplayValue || foundPriceDelta.optionPriceDisplay) {
if (query.configureForm.useKitPrice === 'y') {
if (currentPriceQuote.priceValue) {
const diff = currentPriceQuote.priceValue - parseFloat(foundPriceDelta.optionPriceDisplay.optionPrice);
priceDelta =
diff === 0 ? `$${diff}` : diff < 0 ? `+$${Math.abs(diff).toFixed(2)}` : `-$${diff.toFixed(2)}`;
}
} else if (
parseFloat(
foundPriceDelta?.priceDeltaDisplayValue?.priceDeltaValue ||
foundPriceDelta?.optionPriceDisplay?.optionPrice
) !== 0
) {
const priceDeltaValue =
foundPriceDelta?.priceDeltaDisplayValue?.priceDeltaValueDisplay ||
foundPriceDelta?.optionPriceDisplay?.optionPrice;
const sign = priceDeltaValue.startsWith('-') ? '' : '+';
priceDelta = `${sign}${priceDeltaValue}`;
}
}
}
}
const key =
renderDisplayConfig[optionValue] === 'select'
? `${optionGroupType}:${value}`
: `${optionGroupType}:${Object.entries(value)
.map(([k, v]) => `${k}:${v}`)
.join('-')}`;
const getHtml = (itemParam, optionGroupType) => {
const found = customLabelMap[optionGroupType]?.find(item => {
return isEqual(item.variant, itemParam.variants);
});
if (!found) return false;
const data = {id: key, price: priceDelta};
function encode(html) {
return html
.replace(/{{(.*?)}}/g, (match, key) => {
return data[key] || '';
})
.replace(/""/g, '"');
}
const template_html = encode(found.html);
return template_html;
};
const label = optionGroupType === 'chassis' ? Object.values(variantKeyToValue).join(' | ') : item.optionValueName;
const html =
optionGroupType === 'retina_display' || optionGroupType === 'processor'
? getHtml(item, optionGroupType)
: false;
const disabled =
isFetching ||
(selectedOptionGroupTypeToReset === optionGroupType
? item.displayIndicator === 'ENABLED'
: item.displayIndicator === 'DISABLED' || isDisabled);
let className = '';
if (html) {
if (optionGroupType === 'processor') className += styles.processor;
else if (optionGroupType === 'retina_display') className += styles.retinaDisplay;
if (disabled) className += ' isDisabled';
}
const option = {
html,
label,
value,
id: key,
key: optionGroupType,
className,
disabled,
priceDelta,
item,
isChecked: isOptionChecked,
upgradeOptions: upgradeOptionsDiffMap[key],
renderInlineChildren: order.child && grp.subOptionGroupType && checkIfOptionIsParentOfChildVariant(value)
};
if (isOptionChecked) {
option.onClick = null;
} else if (
selectedOptionGroupTypeToReset === optionGroupType &&
!['keyboard', 'software_final', 'software_logic'].includes(optionGroupType)
) {
option.onClick = () => {
addUserActionDebugList(`User Select: ${option.label}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.compareChanges(option);
};
} else {
option.onClick = () => {
addUserActionDebugList(`User Select: ${option.label}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.fetchPNPOptions(option);
};
}
return option;
});
const renderInlineDiffs = nextState => {
const diffs = getDiffs(nextState);
const hiddenOgts = (nextState._hiddenOptionValuesWithFacets || []).map(item => item.optionGroupTypeKey);
return (
<div className="inline-diffs">
<div className="global-header-small">Upgrade Options:</div>
<ul>
{diffs
.filter(diff => optionGroupType !== diff.key && diff.isDiff && !hiddenOgts.includes(diff.key))
.map(diff => {
return (
<li key={diff.key} className={diff.newValue ? 'global-body' : 'global-body-error'}>
{diff.newValue ? diff.newValue : `To be removed: ${diff.key}`}
</li>
);
})}
</ul>
</div>
);
};
const renderSelectorRadio = optionsCustom => {
return (optionsCustom || options).map((option, idx) => {
return (
<>
<SelectorRadioV2
className={option.className}
id={option.id}
key={option.id}
label={option.label}
html={option.html}
priceDelta={option.priceDelta}
inputProps={{
disabled: option.isChecked || option.disabled,
checked: option.isChecked,
onClick: option.onClick
}}
onClick={option.onClick}
/>
{option.upgradeOptions ? renderInlineDiffs(option.upgradeOptions) : null}
{option.renderInlineChildren ? renderInlineOptionValues(option) : null}
</>
);
});
};
const renderSelectorSoftware = () => {
const CATEGORY_INFO = {
software_final: {
label: 'Final Cut Pro',
infoText: 'A huge leap forward for professional video editing.'
},
software_logic: {
label: 'Logic Pro',
infoText: 'Turn your Mac into a professional music studio.'
}
};
return options
.filter(option => {
if (selectedOptionGroupTypeToReset === optionGroupType) {
return true;
} else if (['final_cut_pro', 'logic_pro'].includes(option.value.dimensionSoftware)) {
return !configureForm[optionGroupType] || configureForm[optionGroupType].dimensionSoftware === 'no_thanks';
} else if ('no_thanks' === option.value.dimensionSoftware) {
return !!configureForm[optionGroupType] && configureForm[optionGroupType].dimensionSoftware !== 'no_thanks';
} else {
return true;
}
})
.map(option => {
const {label, infoText} = CATEGORY_INFO[optionGroupType] || {};
const isNoThanks = option.value.dimensionSoftware === 'no_thanks';
return (
<div key={option.id} className={`${option.className} ${styles.formSelectorCategory}`}>
<label className="form-label" htmlFor={option.id}>
<div className="label-container">
<div className="label-text">
<strong>{label}</strong>
<div className="global-body-medium">{infoText}</div>
</div>
<div className="label-text">{option.priceDelta}</div>
</div>
<div className="action-container">
<button
className={`button button-reduced button-margin ${
isNoThanks
? 'button-secondary-alpha icon icon-after icon-close'
: 'button-tertiary icon icon-after icon-plus'
}`}
onClick={() => {
addUserActionDebugList(
`User Select: ${isNoThanks ? 'Remove' : 'Add'} - ${option.label}`,
'separator',
'after-load-slection'
);
pnpPrototypeCustomize.fetchPNPOptions(option);
}}
disabled={option.disabled}
>
<span>{isNoThanks ? 'Remove' : 'Add'}</span>
</button>
</div>
</label>
</div>
);
});
};
const renderSelectorRadio3 = () => {
if (options.length < 3) {
return renderSelectorRadio();
} else {
return (
<ShowFirst3
options={options}
renderComponent={option => {
return (
<SelectorRadio
id={option.id}
key={option.id}
label={option.label}
inputProps={{
disabled: option.isChecked || option.disabled,
checked: option.isChecked,
onClick: () => {
addUserActionDebugList(`User Select: ${option.label}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.fetchPNPOptions(option);
}
}}
/>
);
}}
/>
);
}
};
const renderSelect = (props = {}) => {
const value = isEmpty(optionValue) ? undefined : JSON.stringify(optionValue);
return (
<>
<Select
placeholder={optionGroupType}
value={value}
options={options}
disabled={isDisabled}
onChange={e => {
const label = options.find(item => item.value === e.target.value)?.label;
addUserActionDebugList(`User Select: ${label ? `- ${label}` : ''}`, 'separator', 'after-load-slection');
pnpPrototypeCustomize.fetchPNPOptions({key: optionGroupType, value: JSON.parse(e.target.value)});
}}
{...props}
/>
{options.some(option => option.renderInlineChildren) ? renderInlineOptionValues() : null}
</>
);
};
function CustomConfiguration() {
const getOptionRange = () => {
let range = '';
if (options.length === 0) {
range += 'None.';
} else if (options.length === 1) {
range += options[0].label;
} else if (options.length === 2) {
range += options[0].label + ' or ' + options[1].label;
} else {
range += options[0].label + ' to ' + options[options.length - 1].label;
}
return range;
};
const getDesc = () => {
if (optionGroupType === 'memory') {
return 'Increasing memory lets you multitask even faster and run multiple apps at once';
} else if (optionGroupType === 'storage') {
return 'Get ample space and fast access to your documents, photos, music, videos, and apps.';
} else {
return '';
}
};
let mainOptions = options.filter(option => option.item.displayIndicator !== 'DISABLED');
let otherOptions = options.filter(option => option.item.displayIndicator === 'DISABLED');
const optionRange = ['memory', 'storage'].includes(optionGroupType) ? getOptionRange() : null;
const desc = getDesc();
const selectedOptionValueDisplayName = options.find(option => option.isChecked === true)?.label || '';
const valueDisplayRender = () => {
if (optionGroupType === 'keyboard') {
return !order.disabled ? (
<div className={styles.keyboard}>{renderSelect({placeholder: 'Select your language'})}</div>
) : null;
} else {
return (
<div className="action-container">
{configurationShow[optionGroupType] ? (
<h4>Select your {optionGroupType}</h4>
) : (
<div>
{selectedOptionValueDisplayName && <h4>{selectedOptionValueDisplayName}</h4>}
{optionRange && (
<>
<div className="global-body-medium">Options Available:</div>
<div className="global-body-medium">{optionRange}</div>
</>
)}
</div>
)}
{optionGroupType !== 'keyboard' ? (
!order.disabled ? (
configurationShow[optionGroupType] ? (
<button
className="button button-tertiary icon icon-chevronup"
onClick={e => {
setConfigurationShow({...configurationShow, [optionGroupType]: false});
}}
/>
) : (
<button
className="button button-tertiary icon icon-after icon-chevrondown"
onClick={() => {
setConfigurationShow({...configurationShow, [optionGroupType]: true});
pnpPrototypeCustomize.refreshUpgradeOptions(optionGroupType, otherOptions);
}}
>
Change
</button>
)
) : null
) : null}
</div>
);
}
};
return (
<div className={`form-group ${styles.configuration}`}>
<strong>{optionGroupType}</strong>
{desc ? <div className="global-body-medium">{desc}</div> : null}
{optionRange || selectedOptionValueDisplayName ? <hr /> : null}
{valueDisplayRender()}
<div className="customize-container">
{configurationShow[optionGroupType] ? (
<>
<div className="form-group option-selector-radio">{renderSelectorRadio(mainOptions)}</div>
{otherOptions.length ? (
<>
<hr />
<div className="form-group option-selector-radio">{renderSelectorRadio(otherOptions)}</div>
</>
) : null}
</>
) : null}
</div>
</div>
);
}
const displayType = renderDisplayConfig[optionGroupType];
if (!displayType) {
return <div className="form-group option-selector-radio">{renderSelectorRadio()}</div>;
} else if (displayType === 'select') {
return <div className="form-group option-select">{renderSelect()}</div>;
} else if (displayType === 'selector-category') {
return <div className="form-group option-selector-category">{renderSelectorSoftware()}</div>;
} else if (displayType === 'selector-radio-3') {
return <div className="form-group option-selector-radio">{renderSelectorRadio3()}</div>;
} else if (displayType === 'selector-radio') {
return <div className="form-group option-selector-radio">{renderSelectorRadio()}</div>;
} else if (displayType === 'selector-custom-configuration') {
return <CustomConfiguration />;
} else {
return null;
}
};
const renderHeaderLabel = grp => {
return (
<h4 className="header-label">
<span>
{grp.optionGroupTypeKey}{' '}
{selectedOptionGroupTypeToReset && selectedOptionGroupTypeToReset === grp.optionGroupTypeKey ? (
<OverlayTrigger
trigger={['hover', 'focus']}
placement="right"
popperConfig={{
modifiers: [
{
name: 'offset',
options: {
offset: [0, 5]
}
}
]
}}
overlay={
<Popover className={`${styles.validationsPopover} popover-info`}>
Choosing a option may cause prior selections to change
</Popover>
}
>
<i className={`icon warning icon-exclamationtriangle`} />
</OverlayTrigger>
) : null}
</span>
<button
className="link reset-link"
onClick={() => {
pnpPrototypeCustomize.updateValue({
key: 'selectedOptionGroupTypeToReset',
value: selectedOptionGroupTypeToReset ? null : grp.optionGroupTypeKey
});
}}
disabled={selectedOptionGroupTypeToReset && grp.optionGroupTypeKey !== selectedOptionGroupTypeToReset}
>
{selectedOptionGroupTypeToReset && grp.optionGroupTypeKey === selectedOptionGroupTypeToReset ? (
<LockOpen className="reset-lock-icon" layoutMode="glyphBox" desiredFontSize={13} />
) : (
<Lock className="reset-lock-icon" layoutMode="glyphBox" desiredFontSize={13} />
)}
</button>
</h4>
);
};
const renderOptionValuesWithFacetsItem = (grp, isParent, order) => {
const optionValueToVariantsUnique = unique_optionValueToVariants(grp, configureForm);
if (!optionValueToVariantsUnique.length) {
return null;
}
return (
<div className={`option-group`}>
{isParent ? renderHeaderLabel(grp) : null}
{renderOptionValues(
grp.optionGroupTypeKey,
optionValueToVariantsUnique,
grp,
isParent,
upgradeOptionsDiffMap,
order
)}
</div>
);
};
const renderOptionValuesWithFacets = optionValuesWithFacets => {
const sortedRenderOrder = !isEmpty(optionValuesSortOrder)
? renderOrder.toSorted((a, b) => optionValuesSortOrder[a.parent.id] - optionValuesSortOrder[b.parent.id])
: renderOrder;
return sortedRenderOrder.map(order => {
const grp = findOptionGroup(optionValuesWithFacets, order.parent.optionGroupTypeKey);
if (!grp) return null;
return renderOptionValuesWithFacetsItem(grp, true, order);
});
};
![]() |
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
