Use a single mutable location, event, slot, etc, for each unique resource that keeps track of the local editable client copy and the server copy of the data contained in it. This makes it much simpler to update these data structures as I can take advantage of the v-model bindings in Vue.js and work with the system instead of against it.
84 lines
1.9 KiB
TypeScript
84 lines
1.9 KiB
TypeScript
import type { ApiUser, ApiUserType } from "~/shared/types/api";
|
|
import type { Entity, EntityLiving, Id, Living } from "~/shared/types/common";
|
|
import { DateTime, Zone } from "~/shared/utils/luxon";
|
|
import { ClientEntity } from "~/utils/client-entity";
|
|
|
|
export class ClientUser extends ClientEntity {
|
|
serverName: string | undefined;
|
|
serverType: ApiUserType
|
|
|
|
constructor(
|
|
id: Id,
|
|
updatedAt: DateTime,
|
|
deleted: boolean,
|
|
public name: string | undefined,
|
|
public type: ApiUserType,
|
|
) {
|
|
super(id, updatedAt, deleted);
|
|
this.serverName = name;
|
|
this.serverType = type;
|
|
}
|
|
|
|
override isModified() {
|
|
return (
|
|
super.isModified()
|
|
|| this.name !== this.serverName
|
|
|| this.type !== this.serverType
|
|
);
|
|
}
|
|
|
|
override discard() {
|
|
if (this.isNew()) {
|
|
throw new Error("ClientUser.discard: Cannot discard new entity.")
|
|
}
|
|
this.updatedAt = this.serverUpdatedAt;
|
|
this.deleted = this.serverDeleted;
|
|
this.name = this.serverName;
|
|
this.type = this.serverType;
|
|
}
|
|
|
|
static create(
|
|
id: Id,
|
|
name: string | undefined,
|
|
type: ApiUserType,
|
|
opts: { zone: Zone, locale: string },
|
|
) {
|
|
return new this(
|
|
id,
|
|
DateTime.fromMillis(ClientEntity.newEntityMillis, opts),
|
|
false,
|
|
name,
|
|
type,
|
|
)
|
|
}
|
|
|
|
static fromApi(api: Living<ApiUser>, opts: { zone: Zone, locale: string }) {
|
|
return new this(
|
|
api.id,
|
|
DateTime.fromISO(api.updatedAt, opts),
|
|
false,
|
|
api.name,
|
|
api.type,
|
|
);
|
|
}
|
|
|
|
override apiUpdate(api: Living<ApiUser>, opts: { zone: Zone, locale: string }) {
|
|
const wasModified = this.isModified();
|
|
this.serverUpdatedAt = DateTime.fromISO(api.updatedAt, opts);
|
|
this.serverDeleted = false;
|
|
this.serverName = api.name;
|
|
this.serverType = api.type;
|
|
if (!wasModified || !this.isModified()) {
|
|
this.discard();
|
|
}
|
|
}
|
|
|
|
toApi(): ApiUser {
|
|
return {
|
|
id: this.id,
|
|
updatedAt: toIso(this.updatedAt),
|
|
name: this.name,
|
|
type: this.type,
|
|
};
|
|
}
|
|
}
|