- Added `useAssetPickerController` for managing asset selection logic. - Created `AssetSelectProps` type for defining asset selection properties. - Implemented `AssetPickerDialog` for displaying the asset selection interface. - Developed `AssetPickerList` for rendering the list of selectable assets. - Introduced `AssetSelect` component for integrating the asset picker into forms. - Created `AssetList` component for shared asset listing functionality. - Added tests for workstation creation logic to ensure proper validation. - Implemented workstation asset fields and association fields for managing workstation assets. - Developed workstation lifecycle dialog for managing work profile states. - Added form progress component for visualizing multi-step forms.
104 lines
3.0 KiB
TypeScript
104 lines
3.0 KiB
TypeScript
import { Name, UniqueID } from "@repo/rdx-ddd";
|
|
import { Maybe, Result } from "@repo/rdx-utils";
|
|
|
|
import { AssetCatalogError } from "../asset-definition";
|
|
import type { WorkstationInput } from "../workstation-values";
|
|
import { WorkstationInputSchema } from "../workstation-values";
|
|
|
|
export class WorkstationValues {
|
|
private constructor(
|
|
public readonly computerAssetId: Maybe<UniqueID>,
|
|
public readonly name: Name,
|
|
public readonly active: boolean,
|
|
public readonly siteId: Maybe<UniqueID>,
|
|
public readonly personId: Maybe<UniqueID>,
|
|
public readonly assetIds: readonly UniqueID[]
|
|
) {
|
|
Object.freeze(this);
|
|
}
|
|
|
|
static create(input: WorkstationInput): Result<WorkstationValues, AssetCatalogError> {
|
|
const parsed = WorkstationInputSchema.safeParse(input);
|
|
const name = Name.create(input.name, 100);
|
|
const site = optionalIdentity(input.siteId);
|
|
const person = optionalIdentity(input.personId);
|
|
const computer = optionalIdentity(input.computerAssetId ?? null);
|
|
|
|
if (
|
|
!(
|
|
parsed.success &&
|
|
name.isSuccess &&
|
|
site.isSuccess &&
|
|
person.isSuccess &&
|
|
computer.isSuccess
|
|
)
|
|
) {
|
|
return Result.fail(new AssetCatalogError("INVALID_REQUEST"));
|
|
}
|
|
const ids: UniqueID[] = [];
|
|
|
|
for (const value of parsed.data.assetIds) {
|
|
const id = UniqueID.create(value);
|
|
|
|
if (!id.isSuccess || ids.some((previous) => previous.equals(id.data))) {
|
|
return Result.fail(new AssetCatalogError("INVALID_MEMBERS"));
|
|
}
|
|
ids.push(id.data);
|
|
}
|
|
|
|
if (input.computerAssetId && !input.assetIds.includes(input.computerAssetId)) {
|
|
return Result.fail(new AssetCatalogError("INVALID_MEMBERS"));
|
|
}
|
|
|
|
return Result.ok(
|
|
new WorkstationValues(
|
|
computer.data,
|
|
name.data,
|
|
input.active,
|
|
site.data,
|
|
person.data,
|
|
Object.freeze(ids)
|
|
)
|
|
);
|
|
}
|
|
|
|
toPrimitive(): WorkstationInput {
|
|
return {
|
|
...(this.computerAssetId.getOrUndefined()
|
|
? { computerAssetId: this.computerAssetId.getOrUndefined()?.toPrimitive() }
|
|
: {}),
|
|
name: this.name.toPrimitive(),
|
|
active: this.active,
|
|
siteId: this.siteId.getOrUndefined()?.toPrimitive() ?? null,
|
|
personId: this.personId.getOrUndefined()?.toPrimitive() ?? null,
|
|
assetIds: this.assetIds.map((id) => id.toPrimitive()),
|
|
};
|
|
}
|
|
|
|
equals(other: WorkstationValues) {
|
|
const a = this.toPrimitive();
|
|
const b = other.toPrimitive();
|
|
|
|
return (
|
|
a.computerAssetId === b.computerAssetId &&
|
|
a.name === b.name &&
|
|
a.active === b.active &&
|
|
a.siteId === b.siteId &&
|
|
a.personId === b.personId &&
|
|
a.assetIds.length === b.assetIds.length &&
|
|
a.assetIds.every((id) => b.assetIds.includes(id))
|
|
);
|
|
}
|
|
}
|
|
|
|
function optionalIdentity(value: string | null): Result<Maybe<UniqueID>, AssetCatalogError> {
|
|
if (!value) {
|
|
return Result.ok(Maybe.none());
|
|
}
|
|
const id = UniqueID.create(value);
|
|
|
|
return id.isSuccess
|
|
? Result.ok(Maybe.some(id.data))
|
|
: Result.fail(new AssetCatalogError("INVALID_REQUEST"));
|
|
}
|