feat: asset tags/ids (#142)

* add schema

* run db migration

* bulk seed asset IDs

* breaking: update runtime options

* conditionally increment asset IDs

* update API endpoints

* fix import asset id assignment

* refactor display + marshal/unmarshal

* add docs page

* add to form field

* hide 000-000 values

* update ENV vars
This commit is contained in:
Hayden 2022-11-13 14:17:55 -09:00 committed by GitHub
parent 976f68252d
commit 6dc2ae1bea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 905 additions and 72 deletions

View file

@ -0,0 +1,10 @@
import { BaseAPI, route } from "../base";
import { EnsureAssetIDResult } from "../types/data-contracts";
export class ActionsAPI extends BaseAPI {
ensureAssetIDs() {
return this.http.post<void, EnsureAssetIDResult>({
url: route("/actions/ensure-asset-ids"),
});
}
}

View file

@ -71,6 +71,9 @@ export interface ItemField {
export interface ItemOut {
archived: boolean;
/** @example 0 */
assetId: string;
attachments: ItemAttachment[];
children: ItemSummary[];
createdAt: Date;
@ -131,6 +134,7 @@ export interface ItemSummary {
export interface ItemUpdate {
archived: boolean;
assetId: string;
description: string;
fields: ItemField[];
id: string;
@ -300,6 +304,10 @@ export interface ChangePassword {
new: string;
}
export interface EnsureAssetIDResult {
completed: number;
}
export interface GroupInvitation {
expiresAt: Date;
token: string;

View file

@ -4,6 +4,7 @@ import { LabelsApi } from "./classes/labels";
import { LocationsApi } from "./classes/locations";
import { GroupApi } from "./classes/group";
import { UserApi } from "./classes/users";
import { ActionsAPI } from "./classes/actions";
import { Requests } from "~~/lib/requests";
export class UserClient extends BaseAPI {
@ -12,6 +13,7 @@ export class UserClient extends BaseAPI {
items: ItemsApi;
group: GroupApi;
user: UserApi;
actions: ActionsAPI;
constructor(requests: Requests) {
super(requests);
@ -21,6 +23,7 @@ export class UserClient extends BaseAPI {
this.items = new ItemsApi(requests);
this.group = new GroupApi(requests);
this.user = new UserApi(requests);
this.actions = new ActionsAPI(requests);
Object.freeze(this);
}

View file

@ -120,6 +120,11 @@
label: "Archived",
ref: "archived",
},
{
type: "text",
label: "Asset ID",
ref: "assetId",
},
];
const purchaseFields: FormField[] = [

View file

@ -70,6 +70,19 @@
);
});
const assetID = computed<Details>(() => {
if (item.value?.assetId === "000-000") {
return [];
}
return [
{
name: "Asset ID",
text: item.value?.assetId,
},
];
});
const itemDetails = computed<Details>(() => {
return [
{
@ -100,6 +113,7 @@
name: "Notes",
text: item.value?.notes,
},
...assetID.value,
...item.value.fields.map(field => {
/**
* Support Special URL Syntax

View file

@ -163,6 +163,25 @@
passwordChange.current = "";
passwordChange.loading = false;
}
async function ensureAssetIDs() {
const { isCanceled } = await confirm.open(
"Are you sure you want to ensure all assets have an ID? This will take a while and cannot be undone."
);
if (isCanceled) {
return;
}
const result = await api.actions.ensureAssetIDs();
if (result.error) {
notify.error("Failed to ensure asset IDs.");
return;
}
notify.success(`${result.data.completed} assets have been updated.`);
}
</script>
<template>
@ -286,6 +305,32 @@
</div>
</BaseCard>
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-warning" class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Actions </span>
<template #description>
Apply Actions to your inventory in bulk. These are irreversible actions. Be careful.
</template>
</BaseSectionHeader>
<div class="py-4 border-t-2 border-gray-300">
<div class="grid grid-cols-1 md:grid-cols-4 gap-10">
<div class="col-span-3">
<h4>Manage Asset IDs</h4>
<p class="text-sm">
Ensures that all items in your inventory have a valid asset_id field. This is done by finding the
highest current asset_id field in the database and applying the next value to each item that has an
unset asset_id field. This is done in order of the created_at field.
</p>
</div>
<BaseButton class="btn-primary mt-auto" @click="ensureAssetIDs"> Ensure Asset IDs </BaseButton>
</div>
</div>
</template>
</BaseCard>
<BaseCard>
<template #title>
<BaseSectionHeader>