mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix releases not reloading when selecting namespaces (#2515)
This commit is contained in:
parent
4e231e5749
commit
10bcae24e5
@ -86,7 +86,7 @@ export async function clickWhatsNew(app: Application) {
|
|||||||
export async function clickWelcomeNotification(app: Application) {
|
export async function clickWelcomeNotification(app: Application) {
|
||||||
const itemsText = await app.client.$("div.info-panel").getText();
|
const itemsText = await app.client.$("div.info-panel").getText();
|
||||||
|
|
||||||
if (itemsText === "0 item") {
|
if (itemsText === "0 items") {
|
||||||
// welcome notification should be present, dismiss it
|
// welcome notification should be present, dismiss it
|
||||||
await app.client.waitUntilTextExists("div.message", "Welcome!");
|
await app.client.waitUntilTextExists("div.message", "Welcome!");
|
||||||
await app.client.click("i.Icon.close");
|
await app.client.click("i.Icon.close");
|
||||||
|
|||||||
@ -14,8 +14,18 @@ export interface IChartVersion {
|
|||||||
export class HelmChartStore extends ItemStore<HelmChart> {
|
export class HelmChartStore extends ItemStore<HelmChart> {
|
||||||
@observable versions = observable.map<string, IChartVersion[]>();
|
@observable versions = observable.map<string, IChartVersion[]>();
|
||||||
|
|
||||||
loadAll() {
|
async loadAll() {
|
||||||
return this.loadItems(() => helmChartsApi.list());
|
try {
|
||||||
|
const res = await this.loadItems(() => helmChartsApi.list());
|
||||||
|
|
||||||
|
this.failedLoading = false;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
} catch (error) {
|
||||||
|
this.failedLoading = true;
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getByName(name: string, repo: string) {
|
getByName(name: string, repo: string) {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import { action, IReactionDisposer, observable, reaction, when } from "mobx";
|
import { action, observable, reaction, when } from "mobx";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { HelmRelease, helmReleasesApi, IReleaseCreatePayload, IReleaseUpdatePayload } from "../../api/endpoints/helm-releases.api";
|
import { HelmRelease, helmReleasesApi, IReleaseCreatePayload, IReleaseUpdatePayload } from "../../api/endpoints/helm-releases.api";
|
||||||
import { ItemStore } from "../../item.store";
|
import { ItemStore } from "../../item.store";
|
||||||
@ -10,64 +10,64 @@ import { Notifications } from "../notifications";
|
|||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class ReleaseStore extends ItemStore<HelmRelease> {
|
export class ReleaseStore extends ItemStore<HelmRelease> {
|
||||||
@observable releaseSecrets: Secret[] = [];
|
releaseSecrets = observable.map<string, Secret>();
|
||||||
@observable secretWatcher: IReactionDisposer;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
when(() => secretsStore.isLoaded, () => {
|
when(() => secretsStore.isLoaded, () => {
|
||||||
this.releaseSecrets = this.getReleaseSecrets();
|
this.releaseSecrets.replace(this.getReleaseSecrets());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
watch() {
|
watchAssociatedSecrets(): (() => void) {
|
||||||
this.secretWatcher = reaction(() => secretsStore.items.toJS(), () => {
|
return reaction(() => secretsStore.items.toJS(), () => {
|
||||||
if (this.isLoading) return;
|
if (this.isLoading) return;
|
||||||
const secrets = this.getReleaseSecrets();
|
const newSecrets = this.getReleaseSecrets();
|
||||||
const amountChanged = secrets.length !== this.releaseSecrets.length;
|
const amountChanged = newSecrets.length !== this.releaseSecrets.size;
|
||||||
const labelsChanged = this.releaseSecrets.some(item => {
|
const labelsChanged = newSecrets.some(([id, secret]) => (
|
||||||
const secret = secrets.find(secret => secret.getId() == item.getId());
|
!isEqual(secret.getLabels(), this.releaseSecrets.get(id)?.getLabels())
|
||||||
|
));
|
||||||
if (!secret) return;
|
|
||||||
|
|
||||||
return !isEqual(item.getLabels(), secret.getLabels());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (amountChanged || labelsChanged) {
|
if (amountChanged || labelsChanged) {
|
||||||
this.loadFromContextNamespaces();
|
this.loadFromContextNamespaces();
|
||||||
}
|
}
|
||||||
this.releaseSecrets = [...secrets];
|
this.releaseSecrets.replace(newSecrets);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unwatch() {
|
watchSelecteNamespaces(): (() => void) {
|
||||||
this.secretWatcher();
|
return reaction(() => namespaceStore.context.contextNamespaces, namespaces => {
|
||||||
|
this.loadAll(namespaces);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getReleaseSecrets() {
|
private getReleaseSecrets() {
|
||||||
return secretsStore.getByLabel({ owner: "helm" });
|
return secretsStore
|
||||||
|
.getByLabel({ owner: "helm" })
|
||||||
|
.map(s => [s.getId(), s] as const);
|
||||||
}
|
}
|
||||||
|
|
||||||
getReleaseSecret(release: HelmRelease) {
|
getReleaseSecret(release: HelmRelease) {
|
||||||
const labels = {
|
return secretsStore.getByLabel({
|
||||||
owner: "helm",
|
owner: "helm",
|
||||||
name: release.getName()
|
name: release.getName()
|
||||||
};
|
})
|
||||||
|
.find(secret => secret.getNs() == release.getNs());
|
||||||
return secretsStore.getByLabel(labels)
|
|
||||||
.filter(secret => secret.getNs() == release.getNs())[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async loadAll(namespaces: string[]) {
|
async loadAll(namespaces: string[]) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
this.isLoaded = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const items = await this.loadItems(namespaces);
|
const items = await this.loadItems(namespaces);
|
||||||
|
|
||||||
this.items.replace(this.sortItems(items));
|
this.items.replace(this.sortItems(items));
|
||||||
this.isLoaded = true;
|
this.isLoaded = true;
|
||||||
|
this.failedLoading = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
this.failedLoading = true;
|
||||||
console.error("Loading Helm Chart releases has failed", error);
|
console.error("Loading Helm Chart releases has failed", error);
|
||||||
|
|
||||||
if (error.error) {
|
if (error.error) {
|
||||||
@ -79,17 +79,18 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadFromContextNamespaces(): Promise<void> {
|
async loadFromContextNamespaces(): Promise<void> {
|
||||||
return this.loadAll(namespaceStore.contextNamespaces);
|
return this.loadAll(namespaceStore.context.contextNamespaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadItems(namespaces: string[]) {
|
async loadItems(namespaces: string[]) {
|
||||||
const isLoadingAll = namespaceStore.allowedNamespaces.every(ns => namespaces.includes(ns));
|
const isLoadingAll = namespaceStore.context.allNamespaces?.length > 1
|
||||||
const noAccessibleNamespaces = namespaceStore.context.cluster.accessibleNamespaces.length === 0;
|
&& namespaceStore.context.cluster.accessibleNamespaces.length === 0
|
||||||
|
&& namespaceStore.context.allNamespaces.every(ns => namespaces.includes(ns));
|
||||||
|
|
||||||
if (isLoadingAll && noAccessibleNamespaces) {
|
if (isLoadingAll) {
|
||||||
return helmReleasesApi.list();
|
return helmReleasesApi.list();
|
||||||
} else {
|
} else {
|
||||||
return Promise
|
return Promise // load resources per namespace
|
||||||
.all(namespaces.map(namespace => helmReleasesApi.list(namespace)))
|
.all(namespaces.map(namespace => helmReleasesApi.list(namespace)))
|
||||||
.then(items => items.flat());
|
.then(items => items.flat());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import "./releases.scss";
|
|||||||
|
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { releaseStore } from "./release.store";
|
import { releaseStore } from "./release.store";
|
||||||
import { IReleaseRouteParams, releaseURL } from "./release.route";
|
import { IReleaseRouteParams, releaseURL } from "./release.route";
|
||||||
@ -30,14 +30,11 @@ interface Props extends RouteComponentProps<IReleaseRouteParams> {
|
|||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class HelmReleases extends Component<Props> {
|
export class HelmReleases extends Component<Props> {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// Watch for secrets associated with releases and react to their changes
|
disposeOnUnmount(this, [
|
||||||
releaseStore.watch();
|
releaseStore.watchAssociatedSecrets(),
|
||||||
}
|
releaseStore.watchSelecteNamespaces(),
|
||||||
|
]);
|
||||||
componentWillUnmount() {
|
|
||||||
releaseStore.unwatch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedRelease() {
|
get selectedRelease() {
|
||||||
@ -49,21 +46,16 @@ export class HelmReleases extends Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showDetails = (item: HelmRelease) => {
|
showDetails = (item: HelmRelease) => {
|
||||||
if (!item) {
|
navigation.merge(releaseURL({
|
||||||
navigation.merge(releaseURL());
|
params: {
|
||||||
}
|
name: item.getName(),
|
||||||
else {
|
namespace: item.getNs()
|
||||||
navigation.merge(releaseURL({
|
}
|
||||||
params: {
|
}));
|
||||||
name: item.getName(),
|
|
||||||
namespace: item.getNs()
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hideDetails = () => {
|
hideDetails = () => {
|
||||||
this.showDetails(null);
|
navigation.merge(releaseURL());
|
||||||
};
|
};
|
||||||
|
|
||||||
renderRemoveDialogMessage(selectedItems: HelmRelease[]) {
|
renderRemoveDialogMessage(selectedItems: HelmRelease[]) {
|
||||||
@ -114,30 +106,22 @@ export class HelmReleases extends Component<Props> {
|
|||||||
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
|
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
|
||||||
{ title: "Updated", className: "updated", sortBy: columnId.updated, id: columnId.updated },
|
{ title: "Updated", className: "updated", sortBy: columnId.updated, id: columnId.updated },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(release: HelmRelease) => {
|
renderTableContents={(release: HelmRelease) => [
|
||||||
const version = release.getVersion();
|
release.getName(),
|
||||||
|
release.getNs(),
|
||||||
return [
|
release.getChart(),
|
||||||
release.getName(),
|
release.getRevision(),
|
||||||
release.getNs(),
|
release.getVersion(),
|
||||||
release.getChart(),
|
release.appVersion,
|
||||||
release.getRevision(),
|
{ title: release.getStatus(), className: kebabCase(release.getStatus()) },
|
||||||
<>
|
release.getUpdated(),
|
||||||
{version}
|
]}
|
||||||
</>,
|
renderItemMenu={(release: HelmRelease) => (
|
||||||
release.appVersion,
|
<HelmReleaseMenu
|
||||||
{ title: release.getStatus(), className: kebabCase(release.getStatus()) },
|
release={release}
|
||||||
release.getUpdated(),
|
removeConfirmationMessage={this.renderRemoveDialogMessage([release])}
|
||||||
];
|
/>
|
||||||
}}
|
)}
|
||||||
renderItemMenu={(release: HelmRelease) => {
|
|
||||||
return (
|
|
||||||
<HelmReleaseMenu
|
|
||||||
release={release}
|
|
||||||
removeConfirmationMessage={this.renderRemoveDialogMessage([release])}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
customizeRemoveDialog={(selectedItems: HelmRelease[]) => ({
|
customizeRemoveDialog={(selectedItems: HelmRelease[]) => ({
|
||||||
message: this.renderRemoveDialogMessage(selectedItems)
|
message: this.renderRemoveDialogMessage(selectedItems)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -65,8 +65,18 @@ export class WorkspaceClusterStore extends ItemStore<ClusterItem> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAll() {
|
async loadAll() {
|
||||||
return this.loadItems(() => this.clusters);
|
try {
|
||||||
|
const res = await this.loadItems(() => this.clusters);
|
||||||
|
|
||||||
|
this.failedLoading = false;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
} catch (error) {
|
||||||
|
this.failedLoading = true;
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(clusterItem: ClusterItem) {
|
async remove(clusterItem: ClusterItem) {
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import { namespaceStore } from "./+namespaces/namespace.store";
|
|||||||
|
|
||||||
export interface ClusterContext {
|
export interface ClusterContext {
|
||||||
cluster?: Cluster;
|
cluster?: Cluster;
|
||||||
allNamespaces?: string[]; // available / allowed namespaces from cluster.ts
|
allNamespaces: string[]; // available / allowed namespaces from cluster.ts
|
||||||
contextNamespaces?: string[]; // selected by user (see: namespace-select.tsx)
|
contextNamespaces: string[]; // selected by user (see: namespace-select.tsx)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clusterContext: ClusterContext = {
|
export const clusterContext: ClusterContext = {
|
||||||
|
|||||||
@ -172,6 +172,10 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
return this.props.isReady ?? this.props.store.isLoaded;
|
return this.props.isReady ?? this.props.store.isLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@computed get failedToLoad() {
|
||||||
|
return this.props.store.failedLoading;
|
||||||
|
}
|
||||||
|
|
||||||
@computed get filters() {
|
@computed get filters() {
|
||||||
let { activeFilters } = pageFilters;
|
let { activeFilters } = pageFilters;
|
||||||
const { isSearchable, searchFilters } = this.props;
|
const { isSearchable, searchFilters } = this.props;
|
||||||
@ -281,6 +285,11 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind()
|
||||||
|
toggleFilters() {
|
||||||
|
this.showFilters = !this.showFilters;
|
||||||
|
}
|
||||||
|
|
||||||
renderFilters() {
|
renderFilters() {
|
||||||
const { hideFilters } = this.props;
|
const { hideFilters } = this.props;
|
||||||
const { isReady, filters } = this;
|
const { isReady, filters } = this;
|
||||||
@ -293,6 +302,14 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderNoItems() {
|
renderNoItems() {
|
||||||
|
if (this.failedToLoad) {
|
||||||
|
return <NoItems>Failed to load items.</NoItems>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isReady) {
|
||||||
|
return <Spinner center />;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.filters.length > 0) {
|
if (this.filters.length > 0) {
|
||||||
return (
|
return (
|
||||||
<NoItems>
|
<NoItems>
|
||||||
@ -309,6 +326,14 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
return <NoItems/>;
|
return <NoItems/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderItems() {
|
||||||
|
if (this.props.virtual) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.items.map(item => this.getRow(item.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
renderHeaderContent(placeholders: IHeaderPlaceholders): ReactNode {
|
renderHeaderContent(placeholders: IHeaderPlaceholders): ReactNode {
|
||||||
const { isSearchable, searchFilters } = this.props;
|
const { isSearchable, searchFilters } = this.props;
|
||||||
const { title, filters, search, info } = placeholders;
|
const { title, filters, search, info } = placeholders;
|
||||||
@ -317,7 +342,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
<>
|
<>
|
||||||
{title}
|
{title}
|
||||||
<div className="info-panel box grow">
|
<div className="info-panel box grow">
|
||||||
{this.isReady && info}
|
{info}
|
||||||
</div>
|
</div>
|
||||||
{filters}
|
{filters}
|
||||||
{isSearchable && searchFilters && search}
|
{isSearchable && searchFilters && search}
|
||||||
@ -326,20 +351,17 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderInfo() {
|
renderInfo() {
|
||||||
const { items, isReady, filters } = this;
|
const { items, filters } = this;
|
||||||
const allItemsCount = this.props.store.getTotalCount();
|
const allItemsCount = this.props.store.getTotalCount();
|
||||||
const itemsCount = items.length;
|
const itemsCount = items.length;
|
||||||
const isFiltered = isReady && filters.length > 0;
|
|
||||||
|
|
||||||
if (isFiltered) {
|
|
||||||
const toggleFilters = () => this.showFilters = !this.showFilters;
|
|
||||||
|
|
||||||
|
if (filters.length > 0) {
|
||||||
return (
|
return (
|
||||||
<><a onClick={toggleFilters}>Filtered</a>: {itemsCount} / {allItemsCount}</>
|
<><a onClick={this.toggleFilters}>Filtered</a>: {itemsCount} / {allItemsCount}</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return allItemsCount <= 1 ? `${allItemsCount} item` : `${allItemsCount} items`;
|
return allItemsCount === 1 ? `${allItemsCount} item` : `${allItemsCount} items`;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
@ -412,40 +434,31 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
|
|
||||||
renderList() {
|
renderList() {
|
||||||
const {
|
const {
|
||||||
store, hasDetailsView, addRemoveButtons = {}, virtual, sortingCallbacks, detailsItem,
|
store, hasDetailsView, addRemoveButtons = {}, virtual, sortingCallbacks,
|
||||||
tableProps = {}, tableId
|
detailsItem, className, tableProps = {}, tableId,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { isReady, removeItemsDialog, items } = this;
|
const { removeItemsDialog, items } = this;
|
||||||
const { selectedItems } = store;
|
const { selectedItems } = store;
|
||||||
const selectedItemId = detailsItem && detailsItem.getId();
|
const selectedItemId = detailsItem && detailsItem.getId();
|
||||||
|
const classNames = cssNames(className, "box", "grow", themeStore.activeTheme.type);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="items box grow flex column">
|
<div className="items box grow flex column">
|
||||||
{!isReady && (
|
<Table
|
||||||
<Spinner center/>
|
tableId={tableId}
|
||||||
)}
|
virtual={virtual}
|
||||||
{isReady && (
|
selectable={hasDetailsView}
|
||||||
<Table
|
sortable={sortingCallbacks}
|
||||||
tableId={tableId}
|
getTableRow={this.getRow}
|
||||||
virtual={virtual}
|
items={items}
|
||||||
selectable={hasDetailsView}
|
selectedItemId={selectedItemId}
|
||||||
sortable={sortingCallbacks}
|
noItems={this.renderNoItems()}
|
||||||
getTableRow={this.getRow}
|
className={classNames}
|
||||||
items={items}
|
{...tableProps}
|
||||||
selectedItemId={selectedItemId}
|
>
|
||||||
noItems={this.renderNoItems()}
|
{this.renderTableHeader()}
|
||||||
{...({
|
{this.renderItems()}
|
||||||
...tableProps,
|
</Table>
|
||||||
className: cssNames("box grow", tableProps.className, themeStore.activeTheme.type),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{this.renderTableHeader()}
|
|
||||||
{
|
|
||||||
!virtual && items.map(item => this.getRow(item.getId()))
|
|
||||||
}
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
)}
|
|
||||||
<AddRemoveButtons
|
<AddRemoveButtons
|
||||||
onRemove={selectedItems.length ? removeItemsDialog : null}
|
onRemove={selectedItems.length ? removeItemsDialog : null}
|
||||||
removeTooltip={`Remove selected items (${selectedItems.length})`}
|
removeTooltip={`Remove selected items (${selectedItems.length})`}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export abstract class ItemStore<T extends ItemObject = ItemObject> {
|
|||||||
|
|
||||||
protected defaultSorting = (item: T) => item.getName();
|
protected defaultSorting = (item: T) => item.getName();
|
||||||
|
|
||||||
|
@observable failedLoading = false;
|
||||||
@observable isLoading = false;
|
@observable isLoading = false;
|
||||||
@observable isLoaded = false;
|
@observable isLoaded = false;
|
||||||
@observable items = observable.array<T>([], { deep: false });
|
@observable items = observable.array<T>([], { deep: false });
|
||||||
|
|||||||
@ -146,18 +146,20 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
|
|||||||
|
|
||||||
const items = await this.loadItems({ namespaces, api: this.api });
|
const items = await this.loadItems({ namespaces, api: this.api });
|
||||||
|
|
||||||
this.isLoaded = true;
|
|
||||||
|
|
||||||
if (merge) {
|
if (merge) {
|
||||||
this.mergeItems(items, { replace: false });
|
this.mergeItems(items, { replace: false });
|
||||||
} else {
|
} else {
|
||||||
this.mergeItems(items, { replace: true });
|
this.mergeItems(items, { replace: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isLoaded = true;
|
||||||
|
this.failedLoading = false;
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Loading store items failed", { error, store: this });
|
console.error("Loading store items failed", { error, store: this });
|
||||||
this.resetOnError(error);
|
this.resetOnError(error);
|
||||||
|
this.failedLoading = true;
|
||||||
} finally {
|
} finally {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user