Skip to content

Commit

Permalink
1,351st Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Shyam-Chen committed Feb 3, 2024
1 parent d32e405 commit adda48a
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 34 deletions.
10 changes: 8 additions & 2 deletions src/routes/(backstage)/(playground)/crud-operations/+page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ onBeforeRouteLeave((to, from) => {
</div>

<XTable
v-model:control="state.todosControl"
:loading="state.todosLoading"
:columns="[
{ key: '_id', name: 'Identifier' },
Expand All @@ -92,6 +91,7 @@ onBeforeRouteLeave((to, from) => {
]"
:rows="state.todosRows"
:count="state.todosCount"
:control="state.todosControl"
@change="actions.changeTodos"
>
<template #completed="{ row }">
Expand All @@ -102,7 +102,12 @@ onBeforeRouteLeave((to, from) => {
<div class="flex gap-2">
<XTooltip title="Edit">
<RouterLink :to="`/crud-operations/${row._id}`">
<XButton icon="i-material-symbols-edit-rounded" variant="text" color="info" />
<XButton
icon="i-material-symbols-edit-rounded"
variant="text"
color="info"
size="small"
/>
</RouterLink>
</XTooltip>

Expand All @@ -111,6 +116,7 @@ onBeforeRouteLeave((to, from) => {
icon="i-material-symbols-delete-rounded"
variant="text"
color="danger"
size="small"
@click="
state.deleteDialog = true;
state.deleteContent = row;
Expand Down
60 changes: 38 additions & 22 deletions src/routes/(backstage)/(playground)/crud-operations/[id]/+page.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<script lang="ts" setup>
import { onMounted, onBeforeMount } from 'vue';
import { useRoute } from 'vue-router';
import { XBreadcrumb, XCard, XTextField, XCheckbox, XButton } from '@x/ui';
import {
XBreadcrumb,
XCard,
XProgressBar,
XTextField,
XCheckbox,
XButton,
XLeaveConfirmation,
} from '@x/ui';
import isEqual from 'lodash/isEqual';
// import { isEqual } from 'lodash';
import useStore from './store';
import useSchema from './schema';
Expand All @@ -28,15 +38,21 @@ onBeforeMount(() => {
<XBreadcrumb
:items="[
{ text: 'Playground' },
{ text: 'CRUD operations', to: '/crud-operations' },
{ text: 'Todo' },
{ text: 'CRUD Operations', to: '/crud-operations' },
{ text: route.params.id === 'new' ? 'Add' : 'Edit' },
]"
/>

<h1 class="text-4xl font-extrabold my-4">CRUD Operations - {{ route.params.id }}</h1>
<h1 class="text-4xl font-extrabold my-4">
{{ route.params.id === 'new' ? 'Add' : 'Edit' }}
</h1>

<XCard class="my-8">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<XCard class="my-8 relative">
<XProgressBar v-if="state.todoLoading" class="absolute inset-0" />

<h2 class="text-3xl font-bold">Todo Info</h2>

<div class="grid grid-cols-1 md:grid-cols-2 gap-4 my-6">
<XTextField
v-model:value="state.todoForm.title"
label="Title"
Expand All @@ -48,21 +64,21 @@ onBeforeMount(() => {
<XCheckbox v-model:value="state.todoForm.completed">Completed</XCheckbox>
</div>

<div class="mt-6">
<XButton
v-if="route.params.id === 'new'"
prepend="i-material-symbols-add-rounded"
label="Add"
:loading="state.todoSending"
@click="schema.validate() && actions.add()"
/>
<XButton
v-else
prepend="i-material-symbols-save-rounded"
label="Save"
:loading="state.todoSending"
@click="schema.validate() && actions.save()"
/>
</div>
<XButton
v-if="route.params.id === 'new'"
prepend="i-material-symbols-add-rounded"
label="Add"
:loading="state.todoSending"
@click="schema.validate() && actions.add()"
/>
<XButton
v-else
prepend="i-material-symbols-save-rounded"
label="Save"
:loading="state.todoSending"
@click="schema.validate() && actions.save()"
/>
</XCard>

<XLeaveConfirmation :trigger="!isEqual(state.todo, state.todoForm) && !state.todoSent" />
</template>
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { reactive, readonly } from 'vue';
import { reactive, readonly, toRaw } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { defineStore } from 'vue-storer';
import { useNotification } from '@x/ui';
import { request } from '@x/ui';

import type { State, TodoItem } from './types';

export default defineStore('/crud-operations/:id', () => {
const router = useRouter();
const route = useRoute();
const notification = useNotification();

const state = reactive<State>({
todo: {},
todoLoading: false,
todoForm: {},
todoValdn: {},
Expand All @@ -23,6 +26,7 @@ export default defineStore('/crud-operations/:id', () => {
const response = await request<{ result: TodoItem }>(`/todos/${route.params.id}`);
state.todoLoading = false;
state.todoForm = response._data?.result || {};
state.todo = structuredClone(toRaw(state.todoForm));
},

initial() {
Expand All @@ -41,8 +45,21 @@ export default defineStore('/crud-operations/:id', () => {

if (response.status === 200) {
state.todoSent = true;

notification.actions.add({
message: 'Add successful',
color: 'success',
});

router.replace('/crud-operations');
}

if (response.status === 400) {
notification.actions.add({
message: 'Add failed',
color: 'danger',
});
}
},
async save() {
state.todoSending = true;
Expand All @@ -55,8 +72,22 @@ export default defineStore('/crud-operations/:id', () => {
state.todoSending = false;

if (response.status === 200) {
state.todoSent = true;

notification.actions.add({
message: 'Edit successful',
color: 'success',
});

router.replace('/crud-operations');
}

if (response.status === 400) {
notification.actions.add({
message: 'Edit failed',
color: 'danger',
});
}
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
export interface TodoItem {
export type TodoItem = {
_id?: string;
title?: string;
completed?: boolean;
}
};

export interface State {
export type State = {
todo: TodoItem;
todoLoading: boolean;
todoForm: TodoItem;
todoValdn: Record<keyof TodoItem, string> | Record<string, string>;
todoSending: boolean;
todoSent: boolean;
}
};
10 changes: 5 additions & 5 deletions src/routes/(backstage)/(playground)/crud-operations/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { ComponentProps } from 'vue-component-type-helpers';
import { XTable } from '@x/ui';

export interface TodoItem {
export type TodoItem = {
_id?: string;
title?: string;
completed?: boolean;
}
};

export interface State {
export type State = {
searchForm: {
title?: string;
filter?: number;
Expand All @@ -16,12 +16,12 @@ export interface State {
todosLoading: boolean;
todosRows: TodoItem[];
todosCount: number;
todosControl: {};
todosControl: XTableProps['control'];

deleteDialog: boolean;
deleteExpected: TodoItem['title'];
deleteContent: TodoItem;
deleteLoading: boolean;
}
};

export type XTableProps = ComponentProps<typeof XTable>;

0 comments on commit adda48a

Please sign in to comment.