mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Person: Pick device tracker (#2726)
* Allow picking devices to track * Tweak translation * Update translation
This commit is contained in:
parent
2f2cdad16b
commit
abbfea0b6a
@ -81,6 +81,7 @@
|
||||
"lit-html": "^1.0.0",
|
||||
"marked": "^0.6.0",
|
||||
"mdn-polyfills": "^5.12.0",
|
||||
"memoize-one": "^5.0.0",
|
||||
"moment": "^2.22.2",
|
||||
"preact": "^8.3.1",
|
||||
"preact-compat": "^3.18.4",
|
||||
@ -105,6 +106,7 @@
|
||||
"@gfx/zopfli": "^1.0.9",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/codemirror": "^0.0.71",
|
||||
"@types/memoize-one": "^4.1.0",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"babel-eslint": "^10",
|
||||
"babel-loader": "^8.0.4",
|
||||
|
120
src/components/entity/ha-entities-picker.ts
Normal file
120
src/components/entity/ha-entities-picker.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import {
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
property,
|
||||
html,
|
||||
customElement,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-icon-button/paper-icon-button-light";
|
||||
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import isValidEntityId from "../../common/entity/valid_entity_id";
|
||||
|
||||
import "./ha-entity-picker";
|
||||
// Not a duplicate, type import
|
||||
// tslint:disable-next-line
|
||||
import { HaEntityPickerEntityFilterFunc } from "./ha-entity-picker";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
|
||||
@customElement("ha-entities-picker")
|
||||
class HaEntitiesPickerLight extends LitElement {
|
||||
@property() public hass?: HomeAssistant;
|
||||
@property() public value?: string[];
|
||||
@property() public domainFilter?: string;
|
||||
@property() public pickedEntityLabel?: string;
|
||||
@property() public pickEntityLabel?: string;
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
const currentEntities = this._currentEntities;
|
||||
return html`
|
||||
${currentEntities.map(
|
||||
(entityId) => html`
|
||||
<div>
|
||||
<ha-entity-picker
|
||||
allow-custom-entity
|
||||
.curValue=${entityId}
|
||||
.hass=${this.hass}
|
||||
.domainFilter=${this.domainFilter}
|
||||
.entityFilter=${this._entityFilter}
|
||||
.value=${entityId}
|
||||
.label=${this.pickedEntityLabel}
|
||||
@value-changed=${this._entityChanged}
|
||||
></ha-entity-picker>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
<div>
|
||||
<ha-entity-picker
|
||||
.hass=${this.hass}
|
||||
.domainFilter=${this.domainFilter}
|
||||
.entityFilter=${this._entityFilter}
|
||||
.label=${this.pickEntityLabel}
|
||||
@value-changed=${this._addEntity}
|
||||
></ha-entity-picker>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _entityFilter: HaEntityPickerEntityFilterFunc = (
|
||||
stateObj: HassEntity
|
||||
) => !this.value || !this.value.includes(stateObj.entity_id);
|
||||
|
||||
private get _currentEntities() {
|
||||
return this.value || [];
|
||||
}
|
||||
|
||||
private async _updateEntities(entities) {
|
||||
fireEvent(this, "value-changed", {
|
||||
value: entities,
|
||||
});
|
||||
|
||||
this.value = entities;
|
||||
}
|
||||
|
||||
private _entityChanged(event: PolymerChangedEvent<string>) {
|
||||
event.stopPropagation();
|
||||
const curValue = (event.currentTarget as any).curValue;
|
||||
const newValue = event.detail.value;
|
||||
if (
|
||||
newValue === curValue ||
|
||||
(newValue !== "" && !isValidEntityId(newValue))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (newValue === "") {
|
||||
this._updateEntities(
|
||||
this._currentEntities.filter((ent) => ent !== curValue)
|
||||
);
|
||||
} else {
|
||||
this._updateEntities(
|
||||
this._currentEntities.map((ent) => (ent === curValue ? newValue : ent))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async _addEntity(event: PolymerChangedEvent<string>) {
|
||||
event.stopPropagation();
|
||||
const toAdd = event.detail.value;
|
||||
(event.currentTarget as any).value = "";
|
||||
if (!toAdd) {
|
||||
return;
|
||||
}
|
||||
const currentEntities = this._currentEntities;
|
||||
if (currentEntities.includes(toAdd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateEntities([...currentEntities, toAdd]);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-entities-picker": HaEntitiesPickerLight;
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import "@vaadin/vaadin-combo-box/vaadin-combo-box-light";
|
||||
|
||||
import "./state-badge";
|
||||
|
||||
import computeStateName from "../../common/entity/compute_state_name";
|
||||
import LocalizeMixin from "../../mixins/localize-mixin";
|
||||
import EventsMixin from "../../mixins/events-mixin";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class HaEntityPicker extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-input > paper-icon-button {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 2px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<vaadin-combo-box-light
|
||||
items="[[_states]]"
|
||||
item-value-path="entity_id"
|
||||
item-label-path="entity_id"
|
||||
value="{{value}}"
|
||||
opened="{{opened}}"
|
||||
allow-custom-value="[[allowCustomEntity]]"
|
||||
on-change="_fireChanged"
|
||||
>
|
||||
<paper-input
|
||||
autofocus="[[autofocus]]"
|
||||
label="[[_computeLabel(label, localize)]]"
|
||||
class="input"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
value="[[value]]"
|
||||
disabled="[[disabled]]"
|
||||
>
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="clear-button"
|
||||
icon="hass:close"
|
||||
no-ripple=""
|
||||
hidden$="[[!value]]"
|
||||
>Clear</paper-icon-button
|
||||
>
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="toggle-button"
|
||||
icon="[[_computeToggleIcon(opened)]]"
|
||||
hidden="[[!_states.length]]"
|
||||
>Toggle</paper-icon-button
|
||||
>
|
||||
</paper-input>
|
||||
<template>
|
||||
<style>
|
||||
paper-icon-item {
|
||||
margin: -10px;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
<paper-icon-item>
|
||||
<state-badge state-obj="[[item]]" slot="item-icon"></state-badge>
|
||||
<paper-item-body two-line="">
|
||||
<div>[[_computeStateName(item)]]</div>
|
||||
<div secondary="">[[item.entity_id]]</div>
|
||||
</paper-item-body>
|
||||
</paper-icon-item>
|
||||
</template>
|
||||
</vaadin-combo-box-light>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
allowCustomEntity: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
hass: {
|
||||
type: Object,
|
||||
observer: "_hassChanged",
|
||||
},
|
||||
_hass: Object,
|
||||
_states: {
|
||||
type: Array,
|
||||
computed: "_computeStates(_hass, domainFilter, entityFilter)",
|
||||
},
|
||||
autofocus: Boolean,
|
||||
label: {
|
||||
type: String,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
notify: true,
|
||||
},
|
||||
opened: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer: "_openedChanged",
|
||||
},
|
||||
domainFilter: {
|
||||
type: String,
|
||||
value: null,
|
||||
},
|
||||
entityFilter: {
|
||||
type: Function,
|
||||
value: null,
|
||||
},
|
||||
disabled: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
_computeLabel(label, localize) {
|
||||
return label === undefined
|
||||
? localize("ui.components.entity.entity-picker.entity")
|
||||
: label;
|
||||
}
|
||||
|
||||
_computeStates(hass, domainFilter, entityFilter) {
|
||||
if (!hass) return [];
|
||||
|
||||
let entityIds = Object.keys(hass.states);
|
||||
|
||||
if (domainFilter) {
|
||||
entityIds = entityIds.filter(
|
||||
(eid) => eid.substr(0, eid.indexOf(".")) === domainFilter
|
||||
);
|
||||
}
|
||||
|
||||
let entities = entityIds.sort().map((key) => hass.states[key]);
|
||||
|
||||
if (entityFilter) {
|
||||
entities = entities.filter(entityFilter);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
_computeStateName(state) {
|
||||
return computeStateName(state);
|
||||
}
|
||||
|
||||
_openedChanged(newVal) {
|
||||
if (!newVal) {
|
||||
this._hass = this.hass;
|
||||
}
|
||||
}
|
||||
|
||||
_hassChanged(newVal) {
|
||||
if (!this.opened) {
|
||||
this._hass = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
_computeToggleIcon(opened) {
|
||||
return opened ? "hass:menu-up" : "hass:menu-down";
|
||||
}
|
||||
|
||||
_fireChanged(ev) {
|
||||
ev.stopPropagation();
|
||||
this.fire("change");
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-entity-picker", HaEntityPicker);
|
200
src/components/entity/ha-entity-picker.ts
Normal file
200
src/components/entity/ha-entity-picker.ts
Normal file
@ -0,0 +1,200 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import "@vaadin/vaadin-combo-box/vaadin-combo-box-light";
|
||||
import memoizeOne from "memoize-one";
|
||||
|
||||
import "./state-badge";
|
||||
|
||||
import computeStateName from "../../common/entity/compute_state_name";
|
||||
import {
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
css,
|
||||
CSSResult,
|
||||
property,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
|
||||
export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean;
|
||||
|
||||
const rowRenderer = (
|
||||
root: HTMLElement,
|
||||
_owner,
|
||||
model: { item: HassEntity }
|
||||
) => {
|
||||
if (!root.firstElementChild) {
|
||||
root.innerHTML = `
|
||||
<style>
|
||||
paper-icon-item {
|
||||
margin: -10px;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
<paper-icon-item>
|
||||
<state-badge state-obj="[[item]]" slot="item-icon"></state-badge>
|
||||
<paper-item-body two-line="">
|
||||
<div class='name'>[[_computeStateName(item)]]</div>
|
||||
<div secondary>[[item.entity_id]]</div>
|
||||
</paper-item-body>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
}
|
||||
|
||||
root.querySelector("state-badge")!.stateObj = model.item;
|
||||
root.querySelector(".name")!.textContent = computeStateName(model.item);
|
||||
root.querySelector("[secondary]")!.textContent = model.item.entity_id;
|
||||
};
|
||||
|
||||
class HaEntityPicker extends LitElement {
|
||||
@property({ type: Boolean }) public autofocus?: boolean;
|
||||
@property({ type: Boolean }) public disabled?: boolean;
|
||||
@property({ type: Boolean }) public allowCustomEntity;
|
||||
@property() public hass?: HomeAssistant;
|
||||
@property() public label?: string;
|
||||
@property() public value?: string;
|
||||
@property() public domainFilter?: string;
|
||||
@property() public entityFilter?: HaEntityPickerEntityFilterFunc;
|
||||
@property({ type: Boolean }) private _opened?: boolean;
|
||||
@property() private _hass?: HomeAssistant;
|
||||
|
||||
private _getStates = memoizeOne(
|
||||
(
|
||||
hass: this["hass"],
|
||||
domainFilter: this["domainFilter"],
|
||||
entityFilter: this["entityFilter"]
|
||||
) => {
|
||||
let states: HassEntity[] = [];
|
||||
|
||||
if (!hass) {
|
||||
return [];
|
||||
}
|
||||
let entityIds = Object.keys(hass.states);
|
||||
|
||||
if (domainFilter) {
|
||||
entityIds = entityIds.filter(
|
||||
(eid) => eid.substr(0, eid.indexOf(".")) === domainFilter
|
||||
);
|
||||
}
|
||||
|
||||
states = entityIds.sort().map((key) => hass!.states[key]);
|
||||
|
||||
if (entityFilter) {
|
||||
states = states.filter(
|
||||
(stateObj) =>
|
||||
// We always want to include the entity of the current value
|
||||
stateObj.entity_id === this.value || entityFilter!(stateObj)
|
||||
);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
);
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
|
||||
if (changedProps.has("hass") && !this._opened) {
|
||||
this._hass = this.hass;
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
const states = this._getStates(
|
||||
this._hass,
|
||||
this.domainFilter,
|
||||
this.entityFilter
|
||||
);
|
||||
|
||||
return html`
|
||||
<vaadin-combo-box-light
|
||||
item-value-path="entity_id"
|
||||
item-label-path="entity_id"
|
||||
.items=${states}
|
||||
.value=${this._value}
|
||||
.allowCustomValue=${this.allowCustomEntity}
|
||||
.renderer=${rowRenderer}
|
||||
@opened-changed=${this._openedChanged}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
<paper-input
|
||||
.autofocus=${this.autofocus}
|
||||
.label=${this.label === undefined && this._hass
|
||||
? this._hass.localize("ui.components.entity.entity-picker.entity")
|
||||
: this.label}
|
||||
.value=${this._value}
|
||||
.disabled=${this.disabled}
|
||||
class="input"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
>
|
||||
${this.value
|
||||
? html`
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="clear-button"
|
||||
icon="hass:close"
|
||||
no-ripple
|
||||
>
|
||||
Clear
|
||||
</paper-icon-button>
|
||||
`
|
||||
: ""}
|
||||
${states.length > 0
|
||||
? html`
|
||||
<paper-icon-button
|
||||
slot="suffix"
|
||||
class="toggle-button"
|
||||
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
|
||||
>
|
||||
Toggle
|
||||
</paper-icon-button>
|
||||
`
|
||||
: ""}
|
||||
</paper-input>
|
||||
</vaadin-combo-box-light>
|
||||
`;
|
||||
}
|
||||
|
||||
private get _value() {
|
||||
return this.value || "";
|
||||
}
|
||||
|
||||
private _openedChanged(ev: PolymerChangedEvent<boolean>) {
|
||||
this._opened = ev.detail.value;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: PolymerChangedEvent<string>) {
|
||||
const newValue = ev.detail.value;
|
||||
if (newValue !== this._value) {
|
||||
this.value = ev.detail.value;
|
||||
setTimeout(() => {
|
||||
fireEvent(this, "value-changed", { value: this.value });
|
||||
fireEvent(this, "change");
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
paper-input > paper-icon-button {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 2px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-entity-picker", HaEntityPicker);
|
@ -2,14 +2,15 @@ import {
|
||||
LitElement,
|
||||
html,
|
||||
css,
|
||||
PropertyDeclarations,
|
||||
CSSResult,
|
||||
TemplateResult,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-dialog/paper-dialog";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
|
||||
import "../../../components/entity/ha-entities-picker";
|
||||
import { PersonDetailDialogParams } from "./show-dialog-person-detail";
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { haStyleDialog } from "../../../resources/ha-style";
|
||||
@ -17,24 +18,20 @@ import { HomeAssistant } from "../../../types";
|
||||
import { PersonMutableParams } from "../../../data/person";
|
||||
|
||||
class DialogPersonDetail extends LitElement {
|
||||
public hass!: HomeAssistant;
|
||||
private _name!: string;
|
||||
private _error?: string;
|
||||
private _params?: PersonDetailDialogParams;
|
||||
private _submitting?: boolean;
|
||||
|
||||
static get properties(): PropertyDeclarations {
|
||||
return {
|
||||
_error: {},
|
||||
_name: {},
|
||||
_params: {},
|
||||
};
|
||||
}
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() private _name!: string;
|
||||
@property() private _deviceTrackers!: string[];
|
||||
@property() private _error?: string;
|
||||
@property() private _params?: PersonDetailDialogParams;
|
||||
@property() private _submitting?: boolean;
|
||||
|
||||
public async showDialog(params: PersonDetailDialogParams): Promise<void> {
|
||||
this._params = params;
|
||||
this._error = undefined;
|
||||
this._name = this._params.entry ? this._params.entry.name : "";
|
||||
this._deviceTrackers = this._params.entry
|
||||
? this._params.entry.device_trackers || []
|
||||
: [];
|
||||
await this.updateComplete;
|
||||
}
|
||||
|
||||
@ -64,6 +61,23 @@ class DialogPersonDetail extends LitElement {
|
||||
error-message="Name is required"
|
||||
.invalid=${nameInvalid}
|
||||
></paper-input>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.person.detail.device_tracker_intro"
|
||||
)}
|
||||
</p>
|
||||
<ha-entities-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._deviceTrackers}
|
||||
domainFilter="device_tracker"
|
||||
.pickedEntityLabel=${this.hass.localize(
|
||||
"ui.panel.config.person.detail.device_tracker_picked"
|
||||
)}
|
||||
.pickEntityLabel=${this.hass.localize(
|
||||
"ui.panel.config.person.detail.device_tracker_pick"
|
||||
)}
|
||||
@value-changed=${this._deviceTrackersChanged}
|
||||
></ha-entities-picker>
|
||||
</div>
|
||||
</paper-dialog-scrollable>
|
||||
<div class="paper-dialog-buttons">
|
||||
@ -94,14 +108,19 @@ class DialogPersonDetail extends LitElement {
|
||||
this._name = ev.detail.value;
|
||||
}
|
||||
|
||||
private _deviceTrackersChanged(ev: PolymerChangedEvent<string[]>) {
|
||||
this._error = undefined;
|
||||
this._deviceTrackers = ev.detail.value;
|
||||
}
|
||||
|
||||
private async _updateEntry() {
|
||||
this._submitting = true;
|
||||
try {
|
||||
const values: PersonMutableParams = {
|
||||
name: this._name.trim(),
|
||||
device_trackers: this._deviceTrackers,
|
||||
// Temp, we will add this in a future PR.
|
||||
user_id: null,
|
||||
device_trackers: [],
|
||||
};
|
||||
if (this._params!.entry) {
|
||||
await this._params!.updateEntry(values);
|
||||
|
@ -783,8 +783,14 @@
|
||||
}
|
||||
},
|
||||
"person": {
|
||||
"caption": "People",
|
||||
"description": "Manage the people in Home Assistant."
|
||||
"caption": "Persons",
|
||||
"description": "Manage the persons that Home Assistant tracks.",
|
||||
"detail": {
|
||||
"name": "Name",
|
||||
"device_tracker_intro": "Select the devices that belong to this person.",
|
||||
"device_tracker_picked": "Track Device",
|
||||
"device_tracker_pick": "Pick device to track"
|
||||
}
|
||||
},
|
||||
"integrations": {
|
||||
"caption": "Integrations",
|
||||
|
@ -29,6 +29,13 @@ declare global {
|
||||
getComputedStyleValue(element, propertyName);
|
||||
};
|
||||
}
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"value-changed": {
|
||||
value: unknown;
|
||||
};
|
||||
change: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export interface WebhookError {
|
||||
|
10
yarn.lock
10
yarn.lock
@ -1642,6 +1642,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/launchpad/-/launchpad-0.6.0.tgz#37296109b7f277f6e6c5fd7e0c0706bc918fbb51"
|
||||
integrity sha1-NylhCbfyd/bmxf1+DAcGvJGPu1E=
|
||||
|
||||
"@types/memoize-one@^4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/memoize-one/-/memoize-one-4.1.0.tgz#62119f26055b3193ae43ca1882c5b29b88b71ece"
|
||||
integrity sha512-cmSgi6JMX/yBwgpVm4GooNWIH+vEeJoa8FAa6ExOhpJbC0Juq32/uYKiKb3VPSqrEA0aOnjvwZanla3O1WZMbw==
|
||||
|
||||
"@types/merge-stream@^1.0.28":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/merge-stream/-/merge-stream-1.1.2.tgz#a880ff66b1fbbb5eef4958d015c5947a9334dbb1"
|
||||
@ -9466,6 +9471,11 @@ mem@^4.0.0:
|
||||
mimic-fn "^1.0.0"
|
||||
p-is-promise "^1.1.0"
|
||||
|
||||
memoize-one@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.0.tgz#d55007dffefb8de7546659a1722a5d42e128286e"
|
||||
integrity sha512-7g0+ejkOaI9w5x6LvQwmj68kUj6rxROywPSCqmclG/HBacmFnZqhVscQ8kovkn9FBCNJmOz6SY42+jnvZzDWdw==
|
||||
|
||||
memory-fs@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290"
|
||||
|
Loading…
x
Reference in New Issue
Block a user