mirror of
https://github.com/outline/outline.git
synced 2025-03-28 14:34:35 +00:00
fix: Initials do not display on notification avatars (#5803)
This commit is contained in:
@ -3,8 +3,8 @@ import { shallow } from "enzyme";
|
||||
import { TFunction } from "i18next";
|
||||
import * as React from "react";
|
||||
import { getI18n } from "react-i18next";
|
||||
import { DEFAULT_PAGINATION_LIMIT } from "~/stores/BaseStore";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import { DEFAULT_PAGINATION_LIMIT } from "~/stores/base/Store";
|
||||
import { runAllPromises } from "~/test/support";
|
||||
import { Component as PaginatedList } from "./PaginatedList";
|
||||
|
||||
|
@ -5,8 +5,8 @@ import * as React from "react";
|
||||
import { withTranslation, WithTranslation } from "react-i18next";
|
||||
import { Waypoint } from "react-waypoint";
|
||||
import { CompositeStateReturn } from "reakit/Composite";
|
||||
import { DEFAULT_PAGINATION_LIMIT } from "~/stores/BaseStore";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import { DEFAULT_PAGINATION_LIMIT } from "~/stores/base/Store";
|
||||
import ArrowKeyNavigation from "~/components/ArrowKeyNavigation";
|
||||
import DelayedMount from "~/components/DelayedMount";
|
||||
import PlaceholderList from "~/components/List/Placeholder";
|
||||
|
@ -317,7 +317,7 @@ class WebsocketProvider extends React.Component<Props> {
|
||||
});
|
||||
}
|
||||
|
||||
auth.team?.updateFromJson(event);
|
||||
auth.team?.updateData(event);
|
||||
});
|
||||
|
||||
this.socket.on(
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as React from "react";
|
||||
import BaseModel from "~/models/BaseModel";
|
||||
import Model from "~/models/base/Model";
|
||||
import useStores from "./useStores";
|
||||
|
||||
/**
|
||||
@ -9,7 +9,7 @@ import useStores from "./useStores";
|
||||
* @param entity The model or model id
|
||||
* @returns The policy for the model
|
||||
*/
|
||||
export default function usePolicy(entity?: string | BaseModel | null) {
|
||||
export default function usePolicy(entity?: string | Model | null) {
|
||||
const { policies } = useStores();
|
||||
const triggered = React.useRef(false);
|
||||
const entityId = entity
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class ApiKey extends BaseModel {
|
||||
class ApiKey extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { computed, observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class AuthenticationProvider extends BaseModel {
|
||||
class AuthenticationProvider extends Model {
|
||||
id: string;
|
||||
|
||||
displayName: string;
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
import { sortNavigationNodes } from "@shared/utils/collections";
|
||||
import type CollectionsStore from "~/stores/CollectionsStore";
|
||||
import Document from "~/models/Document";
|
||||
import ParanoidModel from "~/models/ParanoidModel";
|
||||
import ParanoidModel from "~/models/base/ParanoidModel";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { observable } from "mobx";
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class CollectionGroupMembership extends BaseModel {
|
||||
class CollectionGroupMembership extends Model {
|
||||
id: string;
|
||||
|
||||
groupId: string;
|
||||
|
@ -3,10 +3,11 @@ import { computed, observable } from "mobx";
|
||||
import { now } from "mobx-utils";
|
||||
import type { ProsemirrorData } from "@shared/types";
|
||||
import User from "~/models/User";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
import Relation from "./decorators/Relation";
|
||||
|
||||
class Comment extends BaseModel {
|
||||
class Comment extends Model {
|
||||
/**
|
||||
* Map to keep track of which users are currently typing a reply in this
|
||||
* comments thread.
|
||||
@ -40,18 +41,16 @@ class Comment extends BaseModel {
|
||||
@observable
|
||||
documentId: string;
|
||||
|
||||
createdAt: string;
|
||||
|
||||
@Relation(() => User)
|
||||
createdBy: User;
|
||||
|
||||
createdById: string;
|
||||
|
||||
resolvedAt: string;
|
||||
|
||||
@Relation(() => User)
|
||||
resolvedBy: User;
|
||||
|
||||
updatedAt: string;
|
||||
|
||||
/**
|
||||
* An array of users that are currently typing a reply in this comments thread.
|
||||
*/
|
||||
@ -60,7 +59,7 @@ class Comment extends BaseModel {
|
||||
return Array.from(this.typingUsers.entries())
|
||||
.filter(([, lastReceivedDate]) => lastReceivedDate > subSeconds(now(), 3))
|
||||
.map(([userId]) => this.store.rootStore.users.get(userId))
|
||||
.filter(Boolean);
|
||||
.filter(Boolean) as User[];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@ import { isRTL } from "@shared/utils/rtl";
|
||||
import DocumentsStore from "~/stores/DocumentsStore";
|
||||
import User from "~/models/User";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import ParanoidModel from "./ParanoidModel";
|
||||
import View from "./View";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
type SaveOptions = {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import BaseModel from "./BaseModel";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
import Relation from "./decorators/Relation";
|
||||
|
||||
class Event extends BaseModel {
|
||||
class Event extends Model {
|
||||
id: string;
|
||||
|
||||
name: string;
|
||||
@ -18,8 +19,7 @@ class Event extends BaseModel {
|
||||
|
||||
userId: string;
|
||||
|
||||
createdAt: string;
|
||||
|
||||
@Relation(() => User)
|
||||
actor: User;
|
||||
|
||||
data: {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { computed } from "mobx";
|
||||
import { FileOperationFormat, FileOperationType } from "@shared/types";
|
||||
import { bytesToHumanReadable } from "@shared/utils/files";
|
||||
import BaseModel from "./BaseModel";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class FileOperation extends BaseModel {
|
||||
class FileOperation extends Model {
|
||||
id: string;
|
||||
|
||||
state: string;
|
||||
@ -23,8 +23,6 @@ class FileOperation extends BaseModel {
|
||||
|
||||
user: User;
|
||||
|
||||
createdAt: string;
|
||||
|
||||
@computed
|
||||
get sizeInMB(): string {
|
||||
return bytesToHumanReadable(this.size);
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class Group extends BaseModel {
|
||||
class Group extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
@ -12,8 +12,6 @@ class Group extends BaseModel {
|
||||
name: string;
|
||||
|
||||
memberCount: number;
|
||||
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export default Group;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import BaseModel from "./BaseModel";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class GroupMembership extends BaseModel {
|
||||
class GroupMembership extends Model {
|
||||
id: string;
|
||||
|
||||
userId: string;
|
||||
|
@ -4,10 +4,10 @@ import type {
|
||||
IntegrationSettings,
|
||||
IntegrationType,
|
||||
} from "@shared/types";
|
||||
import BaseModel from "~/models/BaseModel";
|
||||
import Model from "~/models/base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class Integration<T = unknown> extends BaseModel {
|
||||
class Integration<T = unknown> extends Model {
|
||||
id: string;
|
||||
|
||||
type: IntegrationType;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { observable } from "mobx";
|
||||
import { CollectionPermission } from "@shared/types";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class Membership extends BaseModel {
|
||||
class Membership extends Model {
|
||||
id: string;
|
||||
|
||||
userId: string;
|
||||
|
@ -7,13 +7,14 @@ import {
|
||||
documentPath,
|
||||
settingsPath,
|
||||
} from "~/utils/routeHelpers";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Comment from "./Comment";
|
||||
import Document from "./Document";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
import Relation from "./decorators/Relation";
|
||||
|
||||
class Notification extends BaseModel {
|
||||
class Notification extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
@ -35,6 +36,7 @@ class Notification extends BaseModel {
|
||||
/**
|
||||
* The user that triggered the notification.
|
||||
*/
|
||||
@Relation(() => User)
|
||||
actor?: User;
|
||||
|
||||
/**
|
||||
@ -45,6 +47,7 @@ class Notification extends BaseModel {
|
||||
/**
|
||||
* The document that the notification is associated with.
|
||||
*/
|
||||
@Relation(() => Document)
|
||||
document?: Document;
|
||||
|
||||
/**
|
||||
@ -55,6 +58,7 @@ class Notification extends BaseModel {
|
||||
/**
|
||||
* The comment that the notification is associated with.
|
||||
*/
|
||||
@Relation(() => Comment)
|
||||
comment?: Comment;
|
||||
|
||||
/**
|
||||
@ -137,9 +141,9 @@ class Notification extends BaseModel {
|
||||
return this.document ? documentPath(this.document) : "";
|
||||
}
|
||||
case NotificationEventType.CreateCollection: {
|
||||
const collection = this.store.rootStore.documents.get(
|
||||
this.collectionId
|
||||
);
|
||||
const collection = this.collectionId
|
||||
? this.store.rootStore.documents.get(this.collectionId)
|
||||
: undefined;
|
||||
return collection ? collectionPath(collection.url) : "";
|
||||
}
|
||||
case NotificationEventType.MentionedInDocument: {
|
||||
|
@ -1,5 +0,0 @@
|
||||
import BaseModel from "./BaseModel";
|
||||
|
||||
export default abstract class ParanoidModel extends BaseModel {
|
||||
deletedAt: string | undefined;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class Pin extends BaseModel {
|
||||
class Pin extends Model {
|
||||
id: string;
|
||||
collectionId: string;
|
||||
documentId: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class Policy extends BaseModel {
|
||||
class Policy extends Model {
|
||||
id: string;
|
||||
|
||||
abilities: Record<string, boolean>;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { computed } from "mobx";
|
||||
import { isRTL } from "@shared/utils/rtl";
|
||||
import BaseModel from "./BaseModel";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
import Relation from "./decorators/Relation";
|
||||
|
||||
class Revision extends BaseModel {
|
||||
class Revision extends Model {
|
||||
id: string;
|
||||
|
||||
documentId: string;
|
||||
@ -20,8 +21,7 @@ class Revision extends BaseModel {
|
||||
/** HTML string representing the revision as a diff from the previous version */
|
||||
html: string;
|
||||
|
||||
createdAt: string;
|
||||
|
||||
@Relation(() => User)
|
||||
createdBy: User;
|
||||
|
||||
/**
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class SearchQuery extends BaseModel {
|
||||
class SearchQuery extends Model {
|
||||
id: string;
|
||||
|
||||
query: string;
|
||||
|
||||
createdAt: string;
|
||||
|
||||
delete = async () => {
|
||||
this.isSaving = true;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class Share extends BaseModel {
|
||||
class Share extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import type StarsStore from "~/stores/StarsStore";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class Star extends BaseModel {
|
||||
class Star extends Model {
|
||||
id: string;
|
||||
|
||||
@Field
|
||||
@ -13,8 +14,7 @@ class Star extends BaseModel {
|
||||
|
||||
collectionId: string;
|
||||
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
store: StarsStore;
|
||||
|
||||
next(): Star | undefined {
|
||||
const index = this.store.orderedData.indexOf(this);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
/**
|
||||
* A subscription represents a request for a user to receive notifications for
|
||||
* a document.
|
||||
*/
|
||||
class Subscription extends BaseModel {
|
||||
class Subscription extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
@ -21,9 +21,6 @@ class Subscription extends BaseModel {
|
||||
@Field
|
||||
@observable
|
||||
event: string;
|
||||
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export default Subscription;
|
||||
|
@ -2,10 +2,10 @@ import { computed, observable } from "mobx";
|
||||
import { TeamPreferenceDefaults } from "@shared/constants";
|
||||
import { TeamPreference, TeamPreferences } from "@shared/types";
|
||||
import { stringToColor } from "@shared/utils/color";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class Team extends BaseModel {
|
||||
class Team extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
} from "@shared/types";
|
||||
import type { NotificationSettings } from "@shared/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import ParanoidModel from "./ParanoidModel";
|
||||
import ParanoidModel from "./base/ParanoidModel";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class User extends ParanoidModel {
|
||||
@ -96,7 +96,9 @@ class User extends ParanoidModel {
|
||||
get separateEditMode(): boolean {
|
||||
return !this.getPreference(
|
||||
UserPreference.SeamlessEdit,
|
||||
this.store.rootStore.auth.team.getPreference(TeamPreference.SeamlessEdit)
|
||||
this.store.rootStore.auth?.team?.getPreference(
|
||||
TeamPreference.SeamlessEdit
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { action } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import User from "./User";
|
||||
import Model from "./base/Model";
|
||||
|
||||
class View extends BaseModel {
|
||||
class View extends Model {
|
||||
id: string;
|
||||
|
||||
documentId: string;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { observable } from "mobx";
|
||||
import BaseModel from "./BaseModel";
|
||||
import Model from "./base/Model";
|
||||
import Field from "./decorators/Field";
|
||||
|
||||
class WebhookSubscription extends BaseModel {
|
||||
class WebhookSubscription extends Model {
|
||||
@Field
|
||||
@observable
|
||||
id: string;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import pick from "lodash/pick";
|
||||
import { set, observable } from "mobx";
|
||||
import { set, observable, action } from "mobx";
|
||||
import type Store from "~/stores/base/Store";
|
||||
import Logger from "~/utils/Logger";
|
||||
import { getFieldsForModel } from "./decorators/Field";
|
||||
import { getFieldsForModel } from "../decorators/Field";
|
||||
|
||||
export default abstract class BaseModel {
|
||||
export default abstract class Model {
|
||||
@observable
|
||||
id: string;
|
||||
|
||||
@ -17,12 +18,12 @@ export default abstract class BaseModel {
|
||||
|
||||
updatedAt: string;
|
||||
|
||||
store: any;
|
||||
store: Store<Model>;
|
||||
|
||||
constructor(fields: Record<string, any>, store: any) {
|
||||
this.updateFromJson(fields);
|
||||
this.isNew = !this.id;
|
||||
constructor(fields: Record<string, any>, store: Store<Model>) {
|
||||
this.store = store;
|
||||
this.updateData(fields);
|
||||
this.isNew = !this.id;
|
||||
}
|
||||
|
||||
save = async (
|
||||
@ -59,10 +60,14 @@ export default abstract class BaseModel {
|
||||
}
|
||||
};
|
||||
|
||||
updateFromJson = (data: any) => {
|
||||
set(this, { ...data, isNew: false });
|
||||
updateData = action((data: any) => {
|
||||
for (const key in data) {
|
||||
this[key] = data[key];
|
||||
}
|
||||
|
||||
this.isNew = false;
|
||||
this.persistedAttributes = this.toAPI();
|
||||
};
|
||||
});
|
||||
|
||||
fetch = (options?: any) => this.store.fetch(this.id, options);
|
||||
|
||||
@ -134,5 +139,5 @@ export default abstract class BaseModel {
|
||||
);
|
||||
}
|
||||
|
||||
protected persistedAttributes: Partial<BaseModel> = {};
|
||||
protected persistedAttributes: Partial<Model> = {};
|
||||
}
|
5
app/models/base/ParanoidModel.ts
Normal file
5
app/models/base/ParanoidModel.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import Model from "./Model";
|
||||
|
||||
export default abstract class ParanoidModel extends Model {
|
||||
deletedAt: string | undefined;
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
import type Model from "../base/Model";
|
||||
|
||||
const fields = new Map();
|
||||
|
||||
export const getFieldsForModel = (target: any) =>
|
||||
export const getFieldsForModel = (target: Model) =>
|
||||
fields.get(target.constructor.name);
|
||||
|
||||
/**
|
||||
|
59
app/models/decorators/Relation.ts
Normal file
59
app/models/decorators/Relation.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import invariant from "invariant";
|
||||
import type Model from "../base/Model";
|
||||
|
||||
type RelationOptions = {
|
||||
/** Whether this relation is required */
|
||||
required?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* A decorator that records this key as a relation field on the model.
|
||||
* Properties decorated with @Relation will merge and read their data from
|
||||
* the associated store.
|
||||
*
|
||||
* @param classResolver A function that returns the class of the relation
|
||||
* @param options Optional options for the relation definition
|
||||
*/
|
||||
export default function Relation<T extends typeof Model>(
|
||||
classResolver: () => T,
|
||||
options?: RelationOptions
|
||||
) {
|
||||
return function (target: any, propertyKey: string) {
|
||||
const idKey = `${String(propertyKey)}Id`;
|
||||
const relationClass = classResolver();
|
||||
const relationClassName = relationClass.name;
|
||||
|
||||
Object.defineProperty(target, propertyKey, {
|
||||
get() {
|
||||
const id: string | undefined = this[idKey];
|
||||
|
||||
if (!id) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const store =
|
||||
this.store.rootStore[`${relationClassName.toLowerCase()}s`];
|
||||
invariant(store, `Store for ${relationClassName} not found`);
|
||||
|
||||
return store.get(id);
|
||||
},
|
||||
set(newValue: Model | Partial<Model> | undefined) {
|
||||
this[idKey] = newValue ? newValue.id : undefined;
|
||||
|
||||
if (newValue) {
|
||||
const store =
|
||||
this.store.rootStore[`${relationClassName.toLowerCase()}s`];
|
||||
invariant(store, `Store for ${relationClassName} not found`);
|
||||
|
||||
store.add(newValue);
|
||||
} else if (options?.required) {
|
||||
throw new Error(
|
||||
`Cannot set required ${String(propertyKey)} to undefined`
|
||||
);
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
});
|
||||
};
|
||||
}
|
@ -3,7 +3,7 @@ import { observer } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import { PAGINATION_SYMBOL } from "~/stores/BaseStore";
|
||||
import { PAGINATION_SYMBOL } from "~/stores/base/Store";
|
||||
import Collection from "~/models/Collection";
|
||||
import User from "~/models/User";
|
||||
import Avatar from "~/components/Avatar";
|
||||
|
@ -21,7 +21,7 @@ function GroupNew({ onSubmit }: Props) {
|
||||
const { showToast } = useToasts();
|
||||
const [name, setName] = React.useState<string | undefined>();
|
||||
const [isSaving, setIsSaving] = React.useState(false);
|
||||
const [group, setGroup] = React.useState();
|
||||
const [group, setGroup] = React.useState<Group | undefined>();
|
||||
|
||||
const handleSubmit = async (ev: React.SyntheticEvent) => {
|
||||
ev.preventDefault();
|
||||
@ -35,7 +35,8 @@ function GroupNew({ onSubmit }: Props) {
|
||||
);
|
||||
|
||||
try {
|
||||
setGroup(await group.save());
|
||||
await group.save();
|
||||
setGroup(group);
|
||||
} catch (err) {
|
||||
showToast(err.message, {
|
||||
type: "error",
|
||||
|
@ -10,9 +10,9 @@ import styled from "styled-components";
|
||||
import breakpoint from "styled-components-breakpoint";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { DateFilter as TDateFilter } from "@shared/types";
|
||||
import { DEFAULT_PAGINATION_LIMIT } from "~/stores/BaseStore";
|
||||
import { SearchParams } from "~/stores/DocumentsStore";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import { DEFAULT_PAGINATION_LIMIT } from "~/stores/base/Store";
|
||||
import ArrowKeyNavigation from "~/components/ArrowKeyNavigation";
|
||||
import DocumentListItem from "~/components/DocumentListItem";
|
||||
import Empty from "~/components/Empty";
|
||||
|
@ -5,7 +5,7 @@ import * as React from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { useHistory, useLocation } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { PAGINATION_SYMBOL } from "~/stores/BaseStore";
|
||||
import { PAGINATION_SYMBOL } from "~/stores/base/Store";
|
||||
import User from "~/models/User";
|
||||
import Invite from "~/scenes/Invite";
|
||||
import { Action } from "~/components/Actions";
|
||||
|
@ -4,7 +4,7 @@ import { LinkIcon, WarningIcon } from "outline-icons";
|
||||
import * as React from "react";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import { PAGINATION_SYMBOL } from "~/stores/BaseStore";
|
||||
import { PAGINATION_SYMBOL } from "~/stores/base/Store";
|
||||
import Share from "~/models/Share";
|
||||
import Heading from "~/components/Heading";
|
||||
import Notice from "~/components/Notice";
|
||||
|
@ -1,8 +1,8 @@
|
||||
import ApiKey from "~/models/ApiKey";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class ApiKeysStore extends BaseStore<ApiKey> {
|
||||
export default class ApiKeysStore extends Store<ApiKey> {
|
||||
actions = [RPCAction.List, RPCAction.Create, RPCAction.Delete];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -138,8 +138,8 @@ export default class AuthStore {
|
||||
|
||||
@action
|
||||
rehydrate(data: PersistedData) {
|
||||
this.user = data.user ? new User(data.user, this) : undefined;
|
||||
this.team = data.team ? new Team(data.team, this) : undefined;
|
||||
this.user = data.user ? new User(data.user, this as any) : undefined;
|
||||
this.team = data.team ? new Team(data.team, this as any) : undefined;
|
||||
this.collaborationToken = data.collaborationToken;
|
||||
this.lastSignedIn = getCookie("lastSignedIn");
|
||||
this.addPolicies(data.policies);
|
||||
@ -188,8 +188,8 @@ export default class AuthStore {
|
||||
runInAction("AuthStore#fetch", () => {
|
||||
this.addPolicies(res.policies);
|
||||
const { user, team } = res.data;
|
||||
this.user = new User(user, this);
|
||||
this.team = new Team(team, this);
|
||||
this.user = new User(user, this as any);
|
||||
this.team = new Team(team, this as any);
|
||||
this.availableTeams = res.data.availableTeams;
|
||||
this.collaborationToken = res.data.collaborationToken;
|
||||
|
||||
@ -283,13 +283,13 @@ export default class AuthStore {
|
||||
const previousData = this.user?.toAPI();
|
||||
|
||||
try {
|
||||
this.user?.updateFromJson(params);
|
||||
this.user?.updateData(params);
|
||||
const res = await client.post(`/users.update`, params);
|
||||
invariant(res?.data, "User response not available");
|
||||
this.user?.updateFromJson(res.data);
|
||||
this.user?.updateData(res.data);
|
||||
this.addPolicies(res.policies);
|
||||
} catch (err) {
|
||||
this.user?.updateFromJson(previousData);
|
||||
this.user?.updateData(previousData);
|
||||
throw err;
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
@ -310,13 +310,13 @@ export default class AuthStore {
|
||||
const previousData = this.team?.toAPI();
|
||||
|
||||
try {
|
||||
this.team?.updateFromJson(params);
|
||||
this.team?.updateData(params);
|
||||
const res = await client.post(`/team.update`, params);
|
||||
invariant(res?.data, "Team response not available");
|
||||
this.team?.updateFromJson(res.data);
|
||||
this.team?.updateData(res.data);
|
||||
this.addPolicies(res.policies);
|
||||
} catch (err) {
|
||||
this.team?.updateFromJson(previousData);
|
||||
this.team?.updateData(previousData);
|
||||
throw err;
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import AuthenticationProvider from "~/models/AuthenticationProvider";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class AuthenticationProvidersStore extends BaseStore<AuthenticationProvider> {
|
||||
export default class AuthenticationProvidersStore extends Store<AuthenticationProvider> {
|
||||
actions = [RPCAction.List, RPCAction.Update];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -4,10 +4,10 @@ import { CollectionPermission } from "@shared/types";
|
||||
import CollectionGroupMembership from "~/models/CollectionGroupMembership";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore, { PAGINATION_SYMBOL, RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { PAGINATION_SYMBOL, RPCAction } from "./base/Store";
|
||||
|
||||
export default class CollectionGroupMembershipsStore extends BaseStore<CollectionGroupMembership> {
|
||||
export default class CollectionGroupMembershipsStore extends Store<CollectionGroupMembership> {
|
||||
actions = [RPCAction.Create, RPCAction.Delete];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -12,8 +12,8 @@ import {
|
||||
import Collection from "~/models/Collection";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import { AuthorizationError, NotFoundError } from "~/utils/errors";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
enum DocumentPathItemType {
|
||||
Collection = "collection",
|
||||
@ -32,7 +32,7 @@ export type DocumentPath = DocumentPathItem & {
|
||||
path: DocumentPathItem[];
|
||||
};
|
||||
|
||||
export default class CollectionsStore extends BaseStore<Collection> {
|
||||
export default class CollectionsStore extends Store<Collection> {
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, Collection);
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ import Comment from "~/models/Comment";
|
||||
import Document from "~/models/Document";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
export default class CommentsStore extends BaseStore<Comment> {
|
||||
export default class CommentsStore extends Store<Comment> {
|
||||
apiEndpoint = "comments";
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -10,8 +10,8 @@ import { subtractDate } from "@shared/utils/date";
|
||||
import { bytesToHumanReadable } from "@shared/utils/files";
|
||||
import naturalSort from "@shared/utils/naturalSort";
|
||||
import { DocumentValidation } from "@shared/validations";
|
||||
import BaseStore from "~/stores/BaseStore";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import Store from "~/stores/base/Store";
|
||||
import Document from "~/models/Document";
|
||||
import env from "~/env";
|
||||
import { FetchOptions, PaginationParams, SearchResult } from "~/types";
|
||||
@ -38,7 +38,7 @@ type ImportOptions = {
|
||||
publish?: boolean;
|
||||
};
|
||||
|
||||
export default class DocumentsStore extends BaseStore<Document> {
|
||||
export default class DocumentsStore extends Store<Document> {
|
||||
sharedCache: Map<
|
||||
string,
|
||||
{ sharedTree: NavigationNode; team: PublicTeam } | undefined
|
||||
@ -574,7 +574,7 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
invariant(res?.data, "Data should be available");
|
||||
const collection = this.getCollectionForDocument(document);
|
||||
if (collection) {
|
||||
collection.refresh();
|
||||
await collection.refresh();
|
||||
}
|
||||
this.addPolicies(res.policies);
|
||||
return this.add(res.data);
|
||||
@ -686,7 +686,7 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
this.addPolicies(res.policies);
|
||||
const document = this.add(res.data.document);
|
||||
const collection = this.getCollectionForDocument(document);
|
||||
collection?.updateFromJson(res.data.collection);
|
||||
collection?.updateData(res.data.collection);
|
||||
return document;
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
@ -711,7 +711,7 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
|
||||
const collection = this.getCollectionForDocument(document);
|
||||
if (collection) {
|
||||
collection.refresh();
|
||||
await collection.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@ -722,12 +722,12 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
});
|
||||
runInAction("Document#archive", () => {
|
||||
invariant(res?.data, "Data should be available");
|
||||
document.updateFromJson(res.data);
|
||||
document.updateData(res.data);
|
||||
this.addPolicies(res.policies);
|
||||
});
|
||||
const collection = this.getCollectionForDocument(document);
|
||||
if (collection) {
|
||||
collection.refresh();
|
||||
await collection.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
@ -746,12 +746,12 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
});
|
||||
runInAction("Document#restore", () => {
|
||||
invariant(res?.data, "Data should be available");
|
||||
document.updateFromJson(res.data);
|
||||
document.updateData(res.data);
|
||||
this.addPolicies(res.policies);
|
||||
});
|
||||
const collection = this.getCollectionForDocument(document);
|
||||
if (collection) {
|
||||
collection.refresh();
|
||||
await collection.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
@ -764,9 +764,9 @@ export default class DocumentsStore extends BaseStore<Document> {
|
||||
|
||||
runInAction("Document#unpublish", () => {
|
||||
invariant(res?.data, "Data should be available");
|
||||
document.updateFromJson(res.data.document);
|
||||
document.updateData(res.data.document);
|
||||
const collection = this.getCollectionForDocument(document);
|
||||
collection?.updateFromJson(res.data.collection);
|
||||
collection?.updateData(res.data.collection);
|
||||
this.addPolicies(res.policies);
|
||||
});
|
||||
};
|
||||
|
@ -2,10 +2,10 @@ import filter from "lodash/filter";
|
||||
import sortBy from "lodash/sortBy";
|
||||
import { computed } from "mobx";
|
||||
import Event from "~/models/Event";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class EventsStore extends BaseStore<Event> {
|
||||
export default class EventsStore extends Store<Event> {
|
||||
actions = [RPCAction.List];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -2,10 +2,10 @@ import orderBy from "lodash/orderBy";
|
||||
import { computed } from "mobx";
|
||||
import { FileOperationType } from "@shared/types";
|
||||
import FileOperation from "~/models/FileOperation";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class FileOperationsStore extends BaseStore<FileOperation> {
|
||||
export default class FileOperationsStore extends Store<FileOperation> {
|
||||
actions = [RPCAction.List, RPCAction.Info, RPCAction.Delete];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -4,10 +4,10 @@ import { action, runInAction } from "mobx";
|
||||
import GroupMembership from "~/models/GroupMembership";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class GroupMembershipsStore extends BaseStore<GroupMembership> {
|
||||
export default class GroupMembershipsStore extends Store<GroupMembership> {
|
||||
actions = [RPCAction.Create, RPCAction.Delete];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -5,12 +5,12 @@ import naturalSort from "@shared/utils/naturalSort";
|
||||
import Group from "~/models/Group";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
type FetchPageParams = PaginationParams & { query?: string };
|
||||
|
||||
export default class GroupsStore extends BaseStore<Group> {
|
||||
export default class GroupsStore extends Store<Group> {
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, Group);
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ import filter from "lodash/filter";
|
||||
import { computed } from "mobx";
|
||||
import { IntegrationService } from "@shared/types";
|
||||
import naturalSort from "@shared/utils/naturalSort";
|
||||
import BaseStore from "~/stores/BaseStore";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import Store from "~/stores/base/Store";
|
||||
import Integration from "~/models/Integration";
|
||||
|
||||
class IntegrationsStore extends BaseStore<Integration> {
|
||||
class IntegrationsStore extends Store<Integration> {
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, Integration);
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import { CollectionPermission } from "@shared/types";
|
||||
import Membership from "~/models/Membership";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore, { PAGINATION_SYMBOL, RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { PAGINATION_SYMBOL, RPCAction } from "./base/Store";
|
||||
|
||||
export default class MembershipsStore extends BaseStore<Membership> {
|
||||
export default class MembershipsStore extends Store<Membership> {
|
||||
actions = [RPCAction.Create, RPCAction.Delete];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -5,10 +5,10 @@ import { action, computed, runInAction } from "mobx";
|
||||
import Notification from "~/models/Notification";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class NotificationsStore extends BaseStore<Notification> {
|
||||
export default class NotificationsStore extends Store<Notification> {
|
||||
actions = [RPCAction.List, RPCAction.Update];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -3,12 +3,12 @@ import { action, runInAction, computed } from "mobx";
|
||||
import Pin from "~/models/Pin";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
type FetchParams = PaginationParams & { collectionId?: string };
|
||||
|
||||
export default class PinsStore extends BaseStore<Pin> {
|
||||
export default class PinsStore extends Store<Pin> {
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, Pin);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Policy from "~/models/Policy";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
export default class PoliciesStore extends BaseStore<Policy> {
|
||||
export default class PoliciesStore extends Store<Policy> {
|
||||
actions = [];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import invariant from "invariant";
|
||||
import filter from "lodash/filter";
|
||||
import { action, runInAction } from "mobx";
|
||||
import BaseStore, { RPCAction } from "~/stores/BaseStore";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import Store, { RPCAction } from "~/stores/base/Store";
|
||||
import Revision from "~/models/Revision";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
|
||||
export default class RevisionsStore extends BaseStore<Revision> {
|
||||
export default class RevisionsStore extends Store<Revision> {
|
||||
actions = [RPCAction.List, RPCAction.Info];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import uniqBy from "lodash/uniqBy";
|
||||
import { computed } from "mobx";
|
||||
import SearchQuery from "~/models/SearchQuery";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class SearchesStore extends BaseStore<SearchQuery> {
|
||||
export default class SearchesStore extends Store<SearchQuery> {
|
||||
actions = [RPCAction.List, RPCAction.Delete];
|
||||
|
||||
apiEndpoint = "searches";
|
||||
|
@ -6,10 +6,10 @@ import sortBy from "lodash/sortBy";
|
||||
import { action, computed } from "mobx";
|
||||
import Share from "~/models/Share";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class SharesStore extends BaseStore<Share> {
|
||||
export default class SharesStore extends Store<Share> {
|
||||
actions = [
|
||||
RPCAction.Info,
|
||||
RPCAction.List,
|
||||
|
@ -3,10 +3,10 @@ import { action, runInAction, computed } from "mobx";
|
||||
import Star from "~/models/Star";
|
||||
import { PaginationParams } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
export default class StarsStore extends BaseStore<Star> {
|
||||
export default class StarsStore extends Store<Star> {
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore, Star);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Subscription from "~/models/Subscription";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class SubscriptionsStore extends BaseStore<Subscription> {
|
||||
export default class SubscriptionsStore extends Store<Subscription> {
|
||||
actions = [RPCAction.List, RPCAction.Create, RPCAction.Delete];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -5,10 +5,10 @@ import { observable, computed, action, runInAction } from "mobx";
|
||||
import { UserRole } from "@shared/types";
|
||||
import User from "~/models/User";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import BaseStore from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store from "./base/Store";
|
||||
|
||||
export default class UsersStore extends BaseStore<User> {
|
||||
export default class UsersStore extends Store<User> {
|
||||
@observable
|
||||
counts: {
|
||||
active: number;
|
||||
|
@ -3,10 +3,10 @@ import find from "lodash/find";
|
||||
import orderBy from "lodash/orderBy";
|
||||
import reduce from "lodash/reduce";
|
||||
import View from "~/models/View";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class ViewsStore extends BaseStore<View> {
|
||||
export default class ViewsStore extends Store<View> {
|
||||
actions = [RPCAction.List, RPCAction.Create];
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { computed } from "mobx";
|
||||
import WebhookSubscription from "~/models/WebhookSubscription";
|
||||
import BaseStore, { RPCAction } from "./BaseStore";
|
||||
import RootStore from "./RootStore";
|
||||
import Store, { RPCAction } from "./base/Store";
|
||||
|
||||
export default class WebhookSubscriptionsStore extends BaseStore<WebhookSubscription> {
|
||||
export default class WebhookSubscriptionsStore extends Store<WebhookSubscription> {
|
||||
actions = [
|
||||
RPCAction.List,
|
||||
RPCAction.Create,
|
||||
|
@ -4,8 +4,8 @@ import orderBy from "lodash/orderBy";
|
||||
import { observable, action, computed, runInAction } from "mobx";
|
||||
import { Class } from "utility-types";
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import BaseModel from "~/models/BaseModel";
|
||||
import Policy from "~/models/Policy";
|
||||
import Model from "~/models/base/Model";
|
||||
import { PaginationParams, PartialWithId } from "~/types";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import { AuthorizationError, NotFoundError } from "~/utils/errors";
|
||||
@ -25,7 +25,7 @@ export const DEFAULT_PAGINATION_LIMIT = 25;
|
||||
|
||||
export const PAGINATION_SYMBOL = Symbol.for("pagination");
|
||||
|
||||
export default abstract class BaseStore<T extends BaseModel> {
|
||||
export default abstract class Store<T extends Model> {
|
||||
@observable
|
||||
data: Map<string, T> = new Map();
|
||||
|
||||
@ -84,7 +84,7 @@ export default abstract class BaseStore<T extends BaseModel> {
|
||||
const existingModel = this.data.get(item.id);
|
||||
|
||||
if (existingModel) {
|
||||
existingModel.updateFromJson(item);
|
||||
existingModel.updateData(item);
|
||||
return existingModel;
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
import RootStore from "~/stores/RootStore";
|
||||
import env from "~/env";
|
||||
|
||||
const stores = new RootStore();
|
||||
|
||||
// Expose stores on window in development for easier debugging
|
||||
if (env.ENVIRONMENT === "development") {
|
||||
window.stores = stores;
|
||||
}
|
||||
|
||||
export default stores;
|
||||
|
4
app/typings/window.d.ts
vendored
4
app/typings/window.d.ts
vendored
@ -1,3 +1,5 @@
|
||||
import type RootStore from "~/stores/RootStore";
|
||||
|
||||
declare global {
|
||||
interface ImportMeta {
|
||||
/**
|
||||
@ -10,6 +12,8 @@ declare global {
|
||||
dataLayer: any[];
|
||||
gtag: (...args: any[]) => void;
|
||||
|
||||
stores: RootStore;
|
||||
|
||||
DesktopBridge: {
|
||||
/**
|
||||
* The name of the platform running on.
|
||||
|
Reference in New Issue
Block a user