Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add tabs and a project list #7

Merged
merged 1 commit into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"@aklinker1/check": "^1.3.1",
"nanoid": "^5.0.7",
"panzoom": "^9.4.3",
"standard-version": "^9.5.0",
"vue-tsc": "^2.0.10"
Expand Down
63 changes: 63 additions & 0 deletions web/components/AddProjectDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script lang="ts" setup>
import { nanoid } from 'nanoid/non-secure';

const isOpen = useModalModel('add-project');

const { state, closeDialog: _closeDialog } = useDialogState();
const props = computed(() => state.value['add-project']);

const name = ref('');
const url = ref('');

const closeDialog = () => _closeDialog('add-project');

const submit = () => {
if (props.value == null) return;

props.value.onAdd({
id: nanoid(),
name: name.value,
source: { type: 'onshape', url: url.value },
});
closeDialog();
};

const dismiss = () => {
if (props.value == null) return;

props.value.onCancel();
closeDialog();
};
</script>

<template>
<UModal v-model="isOpen">
<form v-if="props" @submit.prevent.stop="submit">
<UCard>
<template #header>{{ props.title }}</template>

<div class="flex flex-col gap-4">
<UFormGroup label="Name" required>
<UInput type="text" placeholder="Enter a name..." v-model="name" />
</UFormGroup>

<UFormGroup label="Onshape Assembly URL" required>
<UInput
type="text"
placeholder="Enter a url..."
v-model="url"
icon="i-heroicons-globe-alt"
/>
</UFormGroup>
</div>

<template #footer>
<div class="flex flex-row-reverse gap-4">
<UButton type="submit">Save</UButton>
<UButton color="gray" @click="dismiss">Cancel</UButton>
</div>
</template>
</UCard>
</form>
</UModal>
</template>
2 changes: 1 addition & 1 deletion web/components/BomTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const rows = computed(() => {
</script>

<template>
<div class="absolute inset-0">
<div class="absolute inset-0 print:relative">
<p v-if="doc == null" class="text-center p-4 opacity-50">
Enter an assembly URL to get started...
</p>
Expand Down
10 changes: 4 additions & 6 deletions web/components/CutlistPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ const { scale, resetZoom, zoomIn, zoomOut } = usePanZoom(container);
No board layouts found
</p>
<div v-else ref="container">
<div class="flex flex-col">
<LayoutList :layouts="data.layouts" />
</div>
<LayoutList :layouts="data.layouts" />
</div>
</template>

Expand All @@ -34,17 +32,17 @@ const { scale, resetZoom, zoomIn, zoomOut } = usePanZoom(container);
</div>
</div>

<!-- Controlls -->
<!-- Controls -->
<div class="absolute bottom-4 right-4 flex gap-4 print:hidden z-10">
<ScaleController
v-if="scale != null"
class="bg-white rounded shadow-2xl"
class="bg-black dark:bg-white rounded shadow-2xl"
:scale="scale"
@reset-zoom="resetZoom"
@zoom-in="zoomIn"
@zoom-out="zoomOut"
/>
<FitController class="bg-white rounded shadow-2xl" />
<FitController class="bg-black dark:bg-white rounded shadow-2xl" />
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion web/components/LayoutListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const length = useFormattedDistance(() => props.layout.stock.lengthM);
>
</p>
<div
class="bg-gray-800 rounded relative ring-1 ring-gray-600 ring-inset"
class="bg-gray-200 dark:bg-gray-800 rounded relative ring-1 ring-gray-400 dark:ring-gray-600 print:ring-black ring-inset"
:style="`width:${widthPx};height:${heightPx}`"
>
<PartListItem
Expand Down
108 changes: 42 additions & 66 deletions web/components/MainSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,87 +54,63 @@ const tab = ref<'bom' | 'stock' | 'settings' | 'warnings'>('bom');

<template>
<div class="flex flex-col">
<header class="flex flex-col gap-4 shrink-0">
<div class="px-8 pt-8">
<h2 class="text-2xl font-bold flex items-center justify-center gap-2">
<UIcon name="i-noto-wood" class="text-primary" />
<span class="text-primary">Onshape</span> Cutlist Generator
</h2>
<div class="flex gap-2 items-center justify-center opacity-50">
<ULink
class="underline"
color="black"
variant="ghost"
square
to="https://github.com/aklinker1/cutlist/wiki"
<header class="flex flex-col shrink-0">
<div
v-if="doc"
class="mx-2 mt-2 p-2 pl-3 flex gap-2 items-start print:m-0 print:p-0"
>
<div class="flex-1 page-break-after">
<h1 class="text-lg font-medium">{{ doc.name }}</h1>
<p class="text-sm opacity-50">by {{ doc.owner.name }}</p>
<a
class="text-sm opacity-50 hidden print:block"
:href="url"
target="_blank"
>{{ url }}</a
>
User Manual
</ULink>
<span>&bull;</span>
<ULink
class="underline"
color="black"
variant="ghost"
square
to="https://github.com/aklinker1/cutlist"
target="_blank"
>
GitHub
</ULink>
</div>
</div>

<UFormGroup class="px-8" label="Assembly URL:">
<UInput
v-model="url"
icon="i-heroicons-magnifying-glass-20-solid"
<UButton
class="print:hidden"
title="Get latest parts from Onshape"
:icon="isFetchingLayouts ? undefined : 'i-heroicons-arrow-path'"
color="gray"
size="sm"
color="white"
:trailing="false"
placeholder="Enter URL..."
:loading="isFetchingDoc"
:loading="isFetchingLayouts"
@click="refresh"
/>
<div
v-if="doc"
class="p-2 pl-3 bg-gray-900 rounded-lg border border-gray-700 mt-2 flex justify-between items-center"
>
<p>
{{ doc.name }}
<span class="text-sm opacity-50">by {{ doc.owner.name }}</span>
</p>
<div class="flex items-center gap-2">
<UButton
title="Get latest parts from Onshape"
:icon="isFetchingLayouts ? undefined : 'i-heroicons-arrow-path'"
color="gray"
size="sm"
:loading="isFetchingLayouts"
@click="refresh"
/>
<UButton
title="Open in Onshape"
:to="url"
target="_blank"
icon="i-heroicons-arrow-top-right-on-square"
color="gray"
size="sm"
/>
</div>
</div>
</UFormGroup>
<UButton
class="print:hidden"
title="Open in Onshape"
:to="url"
target="_blank"
icon="i-heroicons-arrow-top-right-on-square"
color="gray"
size="sm"
/>
<UButton
class="print:hidden"
title="Change Project Source"
icon="i-heroicons-pencil"
color="gray"
size="sm"
/>
</div>

<!-- Print-only BOM list -->
<BomTab class="hidden print:block mt-4 page-break-after" />

<UHorizontalNavigation
:links="links"
class="pl-8 border-b border-gray-200 dark:border-gray-700"
class="pl-2 border-b border-gray-200 dark:border-gray-700 print:hidden"
/>
</header>

<div class="relative flex-1">
<div class="absolute inset-0 overflow-auto">
<BomTab v-if="tab === 'bom'" />
<StockTab v-if="tab === 'stock'" />
<WarningsTab v-if="tab === 'warnings'" class="p-8" />
<StockTab v-else-if="tab === 'stock'" />
<WarningsTab v-else-if="tab === 'warnings'" class="p-8" />
<SettingsTab v-else-if="tab === 'settings'" class="p-8" />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/components/PartListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const showPartNumbers = useShowPartNumbers();
>
<p
v-if="showPartNumbers"
class="w-full text-clip text-gray-400 group-hover:text-primary text-right p-px"
class="w-full text-clip text-gray-500 dark:text-gray-400 print:text-black group-hover:text-primary text-right p-px"
:style="`font-size:${fontSize};line-height:${fontSize}`"
>
{{ placement.partNumber }}
Expand Down
32 changes: 32 additions & 0 deletions web/components/ProjectListItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts" setup>
defineProps<{
project: Project;
}>();

const emit = defineEmits<{
open: [id: string];
delete: [id: string];
}>();
</script>

<template>
<li class="flex">
<UButton
class="flex-1 flex gap-4 !rounded-r-none"
color="gray"
@click="emit('open', project.id)"
>
<UIcon class="w-6 h-6 opacity-50" name="i-heroicons-cube" />
<div class="flex-1 text-left">
<p class="text-lg">{{ project.name }}</p>
<p class="opacity-50 font-normal">Onshape</p>
</div>
</UButton>
<UButton
class="aspect-1 justify-center items-center !rounded-l-none"
color="gray"
icon="i-heroicons-trash"
@click="emit('delete', project.id)"
/>
</li>
</template>
2 changes: 1 addition & 1 deletion web/components/StockMatrixInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const error = ref<unknown>();
<div class="absolute inset-0 flex flex-col p-4 overlfow-auto gap-4">
<textarea
v-model="textModel"
class="font-mono flex-1 resize-none bg-gray-900 border border-gray-700 p-4 outline-none rounded-lg whitespace-pre"
class="font-mono flex-1 resize-none bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 p-4 outline-none rounded-lg whitespace-pre"
/>
<div
v-if="error"
Expand Down
11 changes: 11 additions & 0 deletions web/components/TabList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<ul class="flex overflow-x-auto bg-gray-100 dark:bg-gray-900 print:hidden">
<slot />
</ul>
</template>

<style scoped>
ul {
scrollbar-width: none;
}
</style>
45 changes: 45 additions & 0 deletions web/components/TabListItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts" setup>
defineProps<{
to: string;
name?: string;
hideClose?: boolean;
}>();

const emit = defineEmits<{
close: [];
}>();

const route = useRoute();
</script>

<template>
<li
class="bg-gray-100 dark:bg-gray-900 border-r border-gray-300 dark:border-gray-800"
>
<ULink
class="px-3 flex shrink-0 h-12 justify-between items-center gap-3"
active-class="bg-gray-300 dark:bg-gray-800"
:to="to"
:active="route.path === to"
:title="name"
>
<slot />
<span
v-if="name"
class="min-w-[6rem] max-w-[12rem] truncate text-sm font-medium"
>{{ name }}</span
>
<UButton
v-if="!hideClose"
size="2xs"
icon="i-heroicons-x-mark"
color="white"
variant="soft"
square
:ui="{ rounded: 'rounded-full' }"
title="Close"
@click.stop.prevent="emit('close')"
/>
</ULink>
</li>
</template>
Loading