lodash#uniqueId JavaScript Examples
The following examples show how to use
lodash#uniqueId.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: create.js From holo-schedule with MIT License | 6 votes |
create = (name, { onMessage = noop } = {}) => {
portByName[name] = {
name,
postMessage: message => new Promise((res, rej) => {
const id = uniqueId()
setPendingMessage(id, { res, rej, name, message })
if (!port) {
connectPort()
}
port.postMessage({ isResponse: false, id, name, message })
}),
onMessage,
}
return portByName[name]
}
Example #2
Source File: menu.js From qatrade_admin with MIT License | 6 votes |
/**
* 给菜单数据补充上 path 字段
* https://github.com/d2-projects/d2-admin/issues/209
* @param {Array} menu 原始的菜单数据
*/
function supplementMenuPath (menu) {
return menu.map(e => ({
...e,
path: e.path || uniqueId('d2-menu-empty-'),
...e.children ? {
children: supplementMenuPath(e.children)
} : {}
}))
}
Example #3
Source File: makeUniqueId.jsx From covid19-testing with Apache License 2.0 | 6 votes |
// makeUniqueId creates an ID suitable for identifying an HTML element.
// IDs are unique to the current execution context.
// To automatically provide a unique ID to your React component, use the
// UniqueFieldIs higher order component.
export default function makeUniqueId(label: ?string): string {
const prefix = label ? slug(label.toLowerCase()) : 'unnamed';
// eslint-disable-next-line local/use-emdash
return uniqueId(`${prefix}-`);
}
Example #4
Source File: menu.js From d2admin-permission with MIT License | 6 votes |
/**
* 给菜单数据补充上 path 字段
* https://github.com/d2-projects/d2-admin/issues/209
* @param {Array} menu 原始的菜单数据
*/
function supplementMenuPath (menu) {
return menu.map(e => ({
...e,
path: e.path || uniqueId('d2-menu-empty-'),
...e.children ? {
children: supplementMenuPath(e.children)
} : {}
}))
}
Example #5
Source File: index.js From d2-crud-plus-with-d2admin-starter with MIT License | 6 votes |
/**
* @description 给菜单数据补充上 path 字段
* @description https://github.com/d2-projects/d2-admin/issues/209
* @param {Array} menu 原始的菜单数据
*/
function supplementPath (menu) {
return menu.map(e => ({
...e,
path: e.path || uniqueId('d2-menu-empty-'),
...e.children ? {
children: supplementPath(e.children)
} : {}
}))
}
Example #6
Source File: index.js From django-vue-admin-pro with Apache License 2.0 | 6 votes |
/**
* @description 给菜单数据补充上 path 字段
* @description https://github.com/d2-projects/d2-admin/issues/209
* @param {Array} menu 原始的菜单数据
*/
function supplementPath (menu) {
return menu.map(e => ({
...e,
path: e.path || uniqueId('d2-menu-empty-'),
...e.children ? {
children: supplementPath(e.children)
} : {}
}))
}
Example #7
Source File: useNewTeamMembers.js From datapass with GNU Affero General Public License v3.0 | 6 votes |
useNewTeamMembers = ({
user,
team_members,
contactConfiguration,
}) =>
useMemo(
() =>
chain(contactConfiguration)
.keys()
.map((type) => {
const isMemberAlreadyInitialized = team_members.some(
({ type: t }) => t === type
);
if (isMemberAlreadyInitialized) {
return null;
}
const tmp_id = uniqueId(`tmp_`);
let newTeamMember = { type, tmp_id };
if (type === 'demandeur') {
newTeamMember = {
...newTeamMember,
email: user.email,
};
}
return newTeamMember;
})
.compact()
.value(),
[user, team_members, contactConfiguration]
)
Example #8
Source File: CopyToCliboardButton.js From datapass with GNU Affero General Public License v3.0 | 6 votes |
CopyToCliboardButton = ({ textToCopy }) => {
const [id] = useState(uniqueId());
const clipboard = new ClipboardJS(`#clipboard-${id}`);
clipboard.on('success', function (e) {
e.trigger.classList.add('tooltip-opened');
e.clearSelection();
setTimeout(() => e.trigger.classList.remove('tooltip-opened'), 3000);
});
return (
<button
title="Copier dans le presse papier"
id={`clipboard-${id}`}
data-clipboard-text={textToCopy}
className="inline-icon-button tooltip-controlled"
tooltip="Copié !"
>
<ContentCopyIcon
color={'var(--border-action-high-blue-france)'}
size={14}
/>
</button>
);
}
Example #9
Source File: RadioInput.js From datapass with GNU Affero General Public License v3.0 | 6 votes |
RadioInput = ({
label,
name,
options = [],
value = null,
disabled,
onChange,
required,
}) => {
// id will be set once when the component initially renders, but never again
// we generate an unique id prefixed by the field name
const [id] = useState(uniqueId(name));
return (
<FieldsetWrapper title={label} required={required}>
{options.map(({ id: optionId, label: optionLabel }) => (
<div key={`${id}-${optionId}`} className="fr-radio-group">
<input
type="radio"
name={name}
id={`${id}-${optionId}`}
value={optionId}
checked={value === optionId}
onChange={onChange}
disabled={disabled ? 'disabled' : false}
required={required}
/>
<Label id={`${id}-${optionId}`} label={optionLabel} />
</div>
))}
</FieldsetWrapper>
);
}
Example #10
Source File: CheckboxInput.js From datapass with GNU Affero General Public License v3.0 | 6 votes |
CheckboxInput = ({
label,
helper,
meta,
name,
value = null,
disabled,
onChange,
required,
...rest
}) => {
// id will be set once when the component initially renders, but never again
// we generate an unique id prefixed by the field name
const [id] = useState(uniqueId(name));
return (
<div className="fr-checkbox-group">
<input
onChange={onChange}
disabled={disabled ? 'disabled' : false}
checked={value}
type="checkbox"
name={name}
id={id}
required={required}
{...rest}
/>
<Label
id={id}
label={label}
required={required}
helper={helper}
meta={meta}
/>
</div>
);
}
Example #11
Source File: enhancedArray.js From holo-schedule with MIT License | 6 votes |
createEnhancedArray = (target = [], limit = Infinity) => {
const enhancedArray = reactive(target)
Object.defineProperty(enhancedArray, 'any', {
get() {
return enhancedArray.length > 0
},
})
Object.defineProperty(enhancedArray, 'last', {
get() {
return enhancedArray[enhancedArray.length - 1]
},
})
enhancedArray.add = (item = {}) => {
const indexedItem = { $id: uniqueId(), ...item }
enhancedArray.push(indexedItem)
if (enhancedArray.length > limit) {
enhancedArray.shift()
}
return indexedItem
}
// Changes made by lodash#remove would not traced by Vue
enhancedArray.remove = item => {
const index = enhancedArray.indexOf(item)
if (index === -1) return
enhancedArray.splice(index, 1)
}
return enhancedArray
}
Example #12
Source File: TextAreaInput.js From datapass with GNU Affero General Public License v3.0 | 5 votes |
TextAreaInput = ({
label,
helper,
meta,
name,
placeholder = '',
value = null,
disabled,
onChange,
ariaLabel,
required,
rows = 10,
}) => {
// id will be set once when the component initially renders, but never again
// we generate an unique id prefixed by the field name
const [id] = useState(uniqueId(name));
return (
<div className="fr-input-group">
<Label
id={id}
label={label}
required={required}
helper={helper}
meta={meta}
/>
<textarea
className="fr-input"
rows={rows}
onChange={onChange}
name={name}
placeholder={placeholder}
id={id}
readOnly={disabled}
value={value}
aria-label={ariaLabel}
required={required}
/>
</div>
);
}
Example #13
Source File: SelectInput.js From datapass with GNU Affero General Public License v3.0 | 5 votes |
SelectInput = ({
label,
name,
helper,
meta,
options = [],
value,
disabled,
onChange,
required,
useOtherOption = false,
}) => {
// id will be set once when the component initially renders, but never again
// we generate an unique id prefixed by the field name
const [id] = useState(uniqueId(name));
const isOtherSelected = useMemo(
() => useOtherOption && !options.map(({ id: i }) => i).includes(value),
[useOtherOption, options, value]
);
return (
<SideBySideWrapper>
<div className="fr-select-group">
<Label
id={id}
label={label}
required={required}
helper={helper}
meta={meta}
/>
<select
id={id}
className="fr-select"
name={name}
value={isOtherSelected ? '' : value}
disabled={disabled}
onChange={onChange}
required={required}
>
{options.map(({ id, label: optionLabel }) => (
<option key={id} value={id}>
{optionLabel}
</option>
))}
{useOtherOption && (
<option key="" value="">
Autre
</option>
)}
</select>
</div>
{isOtherSelected && (
<TextInput
label="Précisez :"
name={name}
value={value}
disabled={disabled}
onChange={onChange}
required={required}
ariaLabel={`Précisez le ${label}`}
/>
)}
</SideBySideWrapper>
);
}
Example #14
Source File: Input.js From datapass with GNU Affero General Public License v3.0 | 5 votes |
Input = ({
type = 'text',
label,
helper,
meta,
name,
placeholder = '',
value = null,
disabled,
onChange,
ariaLabel,
required,
...rest
}) => {
// id will be set once when the component initially renders, but never again
// we generate an unique id prefixed by the field name
const [id] = useState(uniqueId(name));
return (
<div className="fr-input-group">
<Label
id={id}
label={label}
required={required}
helper={helper}
meta={meta}
/>
<input
className="fr-input"
type={type}
onChange={onChange}
name={name}
placeholder={placeholder}
id={id}
readOnly={disabled}
value={value}
aria-label={ariaLabel}
required={required}
{...rest}
/>
</div>
);
}
Example #15
Source File: resources.js From file-picker with Apache License 2.0 | 5 votes |
export function buildResource(resource) {
const ext = resource.type !== 'dir' ? _extName(resource.name) : ''
return {
type: resource.type === 'dir' ? 'folder' : resource.type,
// actual file id (string)
id: resource.fileInfo['{http://owncloud.org/ns}fileid'],
// temporary list id, to be used for view only and for uniqueness inside the list
viewId: uniqueId('file-'),
starred: resource.fileInfo['{http://owncloud.org/ns}favorite'] !== '0',
mdate: resource.fileInfo['{DAV:}getlastmodified'],
size: (function () {
if (resource.type === 'dir') {
return resource.fileInfo['{http://owncloud.org/ns}size']
} else {
return resource.fileInfo['{DAV:}getcontentlength']
}
})(),
extension: (function () {
return ext
})(),
name: path.basename(resource.name),
path: resource.name,
permissions: resource.fileInfo['{http://owncloud.org/ns}permissions'] || '',
etag: resource.fileInfo['{DAV:}getetag'],
sharePermissions:
resource.fileInfo['{http://open-collaboration-services.org/ns}share-permissions'],
shareTypes: (function () {
let shareTypes = resource.fileInfo['{http://owncloud.org/ns}share-types']
if (shareTypes) {
shareTypes = chain(shareTypes)
.filter(
(xmlvalue) =>
xmlvalue.namespaceURI === 'http://owncloud.org/ns' &&
xmlvalue.nodeName.split(':')[1] === 'share-type'
)
.map((xmlvalue) => parseInt(xmlvalue.textContent || xmlvalue.text, 10))
.value()
}
return shareTypes || []
})(),
privateLink: resource.fileInfo['{http://owncloud.org/ns}privatelink'],
owner: {
username: resource.fileInfo['{http://owncloud.org/ns}owner-id'],
displayName: resource.fileInfo['{http://owncloud.org/ns}owner-display-name']
},
canUpload: function () {
return this.permissions.indexOf('C') >= 0
},
canDownload: function () {
return this.type !== 'folder'
},
canBeDeleted: function () {
return this.permissions.indexOf('D') >= 0
},
canRename: function () {
return this.permissions.indexOf('N') >= 0
},
canShare: function () {
return this.permissions.indexOf('R') >= 0
},
canCreate: function () {
return this.permissions.indexOf('C') >= 0
},
isMounted: function () {
return this.permissions.indexOf('M') >= 0
},
isReceivedShare: function () {
return this.permissions.indexOf('S') >= 0
}
}
}
Example #16
Source File: index.js From datapass with GNU Affero General Public License v3.0 | 4 votes |
TextInputWithSuggestions = ({
label,
name,
options = [],
value,
disabled,
onChange,
required,
}) => {
// id will be set once when the component initially renders, but never again
// we generate an unique id prefixed by the field name
const [id] = useState(uniqueId(name));
const [suggestions, setSuggestions] = useState([]);
// from https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
const normalize = (string = '') =>
string
.toLowerCase()
.normalize('NFD')
.replace(/\p{Diacritic}/gu, '')
.replace(/[^\w\s]/gi, ' ');
useEffect(() => {
const newSuggestions = chain(options)
.map(({ id, label }) => ({
id,
label,
distance: levenshtein(normalize(value), normalize(label)).similarity,
}))
.sortBy(['distance'])
.reverse()
.filter(({ distance }) => distance > 0.25)
.take(10)
.value();
setSuggestions(newSuggestions);
}, [options, value]);
const [isDropDownOpen, setIsDropDownOpen] = useState(false);
const [activeSuggestion, setActiveSuggestion] = useState(null);
const closeDropDown = () => {
setIsDropDownOpen(false);
setActiveSuggestion(null);
};
const onKeyDown = (e) => {
if (e.key === 'Tab' && isDropDownOpen) {
e.preventDefault();
closeDropDown();
}
if (e.key === 'Enter' && !isDropDownOpen) {
e.preventDefault();
setIsDropDownOpen(true);
}
if (e.key === 'Escape' && isDropDownOpen) {
e.preventDefault();
closeDropDown();
}
if (e.key === 'ArrowDown' && !isDropDownOpen) {
e.preventDefault();
setIsDropDownOpen(true);
setActiveSuggestion(0);
}
if (e.key === 'ArrowDown' && isDropDownOpen && isNull(activeSuggestion)) {
e.preventDefault();
setActiveSuggestion(0);
}
if (e.key === 'ArrowDown' && isDropDownOpen && isNumber(activeSuggestion)) {
e.preventDefault();
setActiveSuggestion(min([activeSuggestion + 1, suggestions.length - 1]));
}
if (e.key === 'ArrowUp' && isDropDownOpen) {
e.preventDefault();
setActiveSuggestion(max([activeSuggestion - 1, 0]));
}
if (e.key === 'Enter' && isDropDownOpen) {
e.preventDefault();
onChange({
target: { name, value: suggestions[activeSuggestion]?.label },
});
closeDropDown();
}
};
const handleChange = (value) => {
closeDropDown();
onChange({ target: { name, value } });
};
return (
<div className="fr-input-group">
<label htmlFor={id}>
{label}
{required && ' *'}
</label>
<input
className="fr-input"
type="text"
onChange={onChange}
name={name}
id={id}
readOnly={disabled}
value={value}
required={required}
onKeyDown={onKeyDown}
onClick={() => setIsDropDownOpen(true)}
onInput={() => setIsDropDownOpen(true)}
/>
{!disabled && isDropDownOpen && !isEmpty(suggestions) && (
<Dropdown onOutsideClick={closeDropDown} fillWidth>
{suggestions.map(({ id, label }, index) => (
<div
key={id}
className={`datapass-text-input-suggestion ${
activeSuggestion === index
? 'datapass-text-input-active-suggestion'
: ''
}`}
onClick={() => handleChange(label)}
>
{label}
</div>
))}
</Dropdown>
)}
</div>
);
}
Example #17
Source File: index.js From datapass with GNU Affero General Public License v3.0 | 4 votes |
ÉquipeSection = ({
initialContacts = {},
responsableTechniqueNeedsMobilePhone = false,
}) => {
const {
isUserEnrollmentLoading,
disabled,
onChange,
enrollment: { team_members = [] },
} = useContext(FormContext);
const { user } = useAuth();
const contactConfiguration = useMemo(() => {
const defaultInitialContacts = {
demandeur: {
header: 'Demandeur',
description: getDefaultDemandeurDescription(),
forceDisable: true,
},
responsable_traitement: {
header: 'Responsable de traitement',
description: getDefaultResponsableTraitementDescription(),
},
delegue_protection_donnees: {
header: 'Délégué à la protection des données',
description: getDefaultDelegueProtectionDonneesDescription(),
},
responsable_technique: {
header: 'Responsable technique',
description: getDefaultResponsableTechniqueDescription(
responsableTechniqueNeedsMobilePhone
),
displayMobilePhoneLabel: responsableTechniqueNeedsMobilePhone,
},
};
return chain(defaultInitialContacts)
.assign(initialContacts)
.omitBy((p) => !p)
.value();
}, [initialContacts, responsableTechniqueNeedsMobilePhone]);
const newTeamMembers = useNewTeamMembers({
user,
team_members,
contactConfiguration,
});
useEffect(() => {
if (!isUserEnrollmentLoading && !disabled && !isEmpty(newTeamMembers)) {
onChange({
target: {
name: 'team_members',
value: [...team_members, ...newTeamMembers],
},
});
}
}, [
isUserEnrollmentLoading,
disabled,
onChange,
team_members,
newTeamMembers,
]);
const displayIdForAdministrator = useMemo(
() => user && user.roles.includes('administrator'),
[user]
);
const updateWithUserInformation = useCallback(
(index) => {
if (team_members[index]?.email !== user.email) {
onChange({
target: {
name: `team_members[${index}].email`,
value: user.email,
},
});
}
if (team_members[index]?.given_name !== user.given_name) {
onChange({
target: {
name: `team_members[${index}].given_name`,
value: user.given_name,
},
});
}
if (team_members[index]?.family_name !== user.family_name) {
onChange({
target: {
name: `team_members[${index}].family_name`,
value: user.family_name,
},
});
}
if (team_members[index]?.phone_number !== user.phone_number) {
onChange({
target: {
name: `team_members[${index}].phone_number`,
value: user.phone_number,
},
});
}
if (team_members[index]?.job !== user.job) {
onChange({
target: {
name: `team_members[${index}].job`,
value: user.job,
},
});
}
},
[team_members, user, onChange]
);
useEffect(() => {
if (!isUserEnrollmentLoading && !disabled && !isEmpty(team_members)) {
const currentDemandeurIndex = team_members.findIndex(
({ type, email }) => type === 'demandeur' && email === user.email
);
if (currentDemandeurIndex !== -1) {
updateWithUserInformation(currentDemandeurIndex);
}
}
}, [
isUserEnrollmentLoading,
disabled,
team_members,
user,
updateWithUserInformation,
]);
const addTeamMemberFactory = (type) => {
const tmp_id = uniqueId(`tmp_`);
const newTeamMember = { type, tmp_id };
return () =>
onChange({
target: {
name: 'team_members',
value: [...team_members, newTeamMember],
},
});
};
const removeTeamMember = (index) => {
onChange({
target: {
name: 'team_members',
value: [
...team_members.slice(0, index),
...team_members.slice(index + 1),
],
},
});
};
return (
<ScrollablePanel scrollableId={SECTION_ID}>
<h2>{SECTION_LABEL}</h2>
<ExpandableQuote title="Comment renseigner la liste des contacts ?" large>
{Object.entries(contactConfiguration).map(([type, { description }]) => (
<p key={type}>{description}</p>
))}
</ExpandableQuote>
<CardContainer flex={false}>
{Object.entries(contactConfiguration).map(
([
type,
{
header,
forceDisable,
displayMobilePhoneLabel,
displayIndividualEmailLabel,
displayGroupEmailLabel,
contactByEmailOnly,
multiple,
},
]) => (
<React.Fragment key={type}>
{team_members
.filter(({ type: t }) => t === type)
.map(({ id, tmp_id, ...team_member }) => (
<Contact
heading={header}
key={id || tmp_id}
id={id}
index={findIndex(team_members, ({ id: i, tmp_id: t_i }) => {
if (id) {
// if id is defined match on id field
return i === id;
}
if (tmp_id) {
// if id is not defined and tmp_id is defined
// match on tmp_id
return t_i === tmp_id;
}
return false;
})}
{...team_member}
displayMobilePhoneLabel={displayMobilePhoneLabel}
displayIndividualEmailLabel={displayIndividualEmailLabel}
displayGroupEmailLabel={displayGroupEmailLabel}
contactByEmailOnly={contactByEmailOnly}
displayIdForAdministrator={displayIdForAdministrator}
disabled={forceDisable || disabled}
onChange={onChange}
onDelete={multiple && !id && removeTeamMember}
onUpdateWithUserInformation={updateWithUserInformation}
canUpdatePersonalInformation={
team_member.email === user.email &&
(team_member.given_name !== user.given_name ||
team_member.family_name !== user.family_name ||
team_member.phone_number !== user.phone_number ||
team_member.job !== user.job)
}
/>
))}
{!disabled && multiple && (
<AddCard
label={`ajouter un ${header.toLowerCase()}`}
onClick={addTeamMemberFactory(type)}
/>
)}
</React.Fragment>
)
)}
</CardContainer>
</ScrollablePanel>
);
}