generated from antfu-collective/vitesse
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from doroudi:doroudi/issue31
Implement colors management section
- Loading branch information
Showing
14 changed files
with
405 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
<script setup lang='ts'> | ||
import { type DataTableColumns, NButton, NIcon } from 'naive-ui/es/components' | ||
import type { RowData } from 'naive-ui/es/data-table/src/interface' | ||
import { | ||
DismissCircle24Regular as DeleteIcon, | ||
Edit32Regular as EditIcon, | ||
AddCircle20Regular as PlusIcon, | ||
} from '@vicons/fluent' | ||
import { storeToRefs } from 'pinia' | ||
import { useDialog, useMessage } from 'naive-ui' | ||
const { t } = useI18n() | ||
const store = useColorStore() | ||
const { colors, isLoading } = storeToRefs(store) | ||
const dialog = useDialog() | ||
const message = useMessage() | ||
onMounted(getItems) | ||
const columns: DataTableColumns<RowData> = [ | ||
{ | ||
title: 'Color', | ||
key: 'color', | ||
width: 250, | ||
render(row) { | ||
return h( | ||
'span', | ||
{ | ||
style: { 'background-color': row.color }, | ||
class: 'color-preview', | ||
}, | ||
) | ||
}, | ||
}, | ||
{ | ||
title: 'Name', | ||
key: 'name', | ||
}, | ||
{ | ||
title: 'Actions', | ||
key: 'actions', | ||
width: 200, | ||
render(row) { | ||
return [ | ||
h( | ||
NButton, | ||
{ | ||
size: 'small', | ||
renderIcon: renderIcon(EditIcon), | ||
ghost: true, | ||
class: 'mr-2', | ||
onClick: () => edit(row), | ||
}, | ||
{ default: () => 'Edit' }, | ||
), | ||
h( | ||
NButton, | ||
{ | ||
size: 'small', | ||
type: 'error', | ||
ghost: true, | ||
renderIcon: renderIcon(DeleteIcon), | ||
onClick: () => handleDeleteItem(row), | ||
}, | ||
{ default: () => 'Delete' }, | ||
), | ||
] | ||
}, | ||
}, | ||
] | ||
const { options } = storeToRefs(store) | ||
const showAddDialog = ref(false) | ||
function renderIcon(icon: any) { | ||
return () => h(NIcon, null, { default: () => h(icon) }) | ||
} | ||
function handleDeleteItem(row: RowData) { | ||
dialog.error({ | ||
title: 'Confirm', | ||
content: 'Are you sure?', | ||
positiveText: 'Yes, Delete', | ||
negativeText: 'Cancel', | ||
onPositiveClick: () => { | ||
store.deleteBrand(row.id) | ||
message.success('Brand was deleted!') | ||
}, | ||
}) | ||
} | ||
function rowKey(row: RowData) { | ||
return row.id | ||
} | ||
function getItems() { | ||
store.getColors(options.value) | ||
} | ||
function handlePageChange(page: number) { | ||
options.value.page = page | ||
getItems() | ||
} | ||
function handleFiltersChange() { | ||
getItems() | ||
} | ||
function createColor() { | ||
showAddDialog.value = true | ||
} | ||
</script> | ||
|
||
<template> | ||
<n-layout> | ||
<n-layout-content> | ||
<div> | ||
<div class="flex items-center mb-5"> | ||
<h1 class="page-title mx-2"> | ||
{{ t('colors.title') }} | ||
</h1> | ||
<NButton type="primary" quaternary round @click="createColor"> | ||
<template #icon> | ||
<NIcon> | ||
<PlusIcon /> | ||
</NIcon> | ||
</template> | ||
{{ t('brands.createButton') }} | ||
</NButton> | ||
</div> | ||
<n-data-table | ||
remote :columns="columns" :data="colors" :loading="isLoading" :pagination="options" | ||
:row-key="rowKey" @update:sorter="handleSorterChange" @update:filters="handleFiltersChange" | ||
@update:page="handlePageChange" | ||
/> | ||
</div> | ||
</n-layout-content> | ||
|
||
<n-drawer v-model:show="showAddDialog" :width="502" placement="right"> | ||
<n-drawer-content closable :title="t('colors.create.title')"> | ||
<CreateColor @close="showAddDialog = false" /> | ||
</n-drawer-content> | ||
</n-drawer> | ||
</n-layout> | ||
</template> | ||
|
||
<style lang='scss'> | ||
.color-preview { | ||
display: inline-block; | ||
width: 2rem; | ||
height: 2rem; | ||
border: solid 3px #FFF; | ||
box-shadow: 0 0 3px 0 #989898; | ||
border-radius: 50%; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<script setup lang='ts'> | ||
import type { FormInst, FormRules } from 'naive-ui/es/form' | ||
import { storeToRefs } from 'pinia' | ||
const emits = defineEmits(['close']) | ||
const colorStore = useColorStore() | ||
const { isLoading } = storeToRefs(colorStore) | ||
const colorItem = ref<ColorCreateModel>({ name: '', color: '#000000' }) | ||
const { t } = useI18n() | ||
const formRef = ref<FormInst | null>(null) | ||
async function create() { | ||
formRef.value?.validate(async (errors: any) => { | ||
if (!errors) { | ||
await colorStore.createColor(colorItem.value) | ||
emits('close') | ||
} | ||
}) | ||
} | ||
const nameInput = ref() | ||
onMounted(() => { | ||
nameInput.value?.focus() | ||
}) | ||
const rules: FormRules = { | ||
name: [ | ||
{ | ||
required: true, | ||
trigger: ['blur', 'change'], | ||
message: t('colors.validations.nameRequired'), | ||
}, | ||
], | ||
// color: [ | ||
// { | ||
// required: true, | ||
// trigger: ['blur', 'change'], | ||
// message: t('colors.validations.colorRequired'), | ||
// }, | ||
// ], | ||
} | ||
</script> | ||
|
||
<template> | ||
<n-form ref="formRef" :model="colorItem" :rules="rules" @submit.prevent="create()"> | ||
<div class="form-control"> | ||
<n-form-item class="mb-5" path="name" :label="t('colors.create.name')"> | ||
<n-input | ||
id="name" ref="nameInput" v-model:value="colorItem.name" autofocus | ||
:placeholder="t('brands.create.brandName')" | ||
/> | ||
</n-form-item> | ||
</div> | ||
<div class="form-control flex flex-col mb-5"> | ||
<n-form-item :label="t('colors.create.color')"> | ||
<n-color-picker | ||
v-model:value="colorItem.color" | ||
:modes="['hex']" :show-alpha="false" | ||
:swatches="[ | ||
'#FFFFFF', | ||
'#18A058', | ||
'#2080F0', | ||
'#F0A020', | ||
'rgba(208, 48, 80, 1)', | ||
]" | ||
/> | ||
</n-form-item> | ||
</div> | ||
|
||
<n-button attr-type="submit" size="large" :block="true" type="primary" :loading="isLoading"> | ||
{{ t('brands.create.buttonTitle') }} | ||
</n-button> | ||
</n-form> | ||
</template> | ||
|
||
<style scoped lang='scss'></style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { rest } from 'msw' | ||
import _ from 'lodash' | ||
import { faker } from '@faker-js/faker' | ||
import { CreatePagedResponse } from '../handlers.utility' | ||
import type { Color, ColorCreateModel } from '~/models/Color' | ||
|
||
const colors = _.times(7, createFakeColor) | ||
const handlers = [ | ||
rest.get('/api/Color', (req, res, ctx) => { | ||
const response = CreatePagedResponse<Color>(req, colors) | ||
return res( | ||
ctx.status(200), | ||
ctx.delay(200), | ||
ctx.json(response), | ||
) | ||
}), | ||
rest.post('/api/color', async (req, res, ctx) => { | ||
const newItem = await req.json<ColorCreateModel>() | ||
const color: Color = { | ||
id: faker.datatype.number({ max: 2000 }).toString(), | ||
name: newItem.name, | ||
color: newItem.color, | ||
} | ||
colors.push(color) | ||
return res( | ||
ctx.status(200), | ||
ctx.delay(200), | ||
ctx.json(color), | ||
) | ||
}), | ||
rest.delete('/api/Color/:id', (req, res, ctx) => { | ||
const id = req.params.id.toString() | ||
const itemIndex = colors.findIndex(x => x.id === id) | ||
colors.splice(itemIndex, 1) | ||
return res( | ||
ctx.delay(1000), | ||
ctx.status(200), | ||
ctx.json(true), | ||
) | ||
}), | ||
|
||
] | ||
|
||
function createFakeColor(): Color { | ||
return { | ||
id: faker.datatype.number().toString(), | ||
name: faker.color.human(), | ||
color: faker.color.rgb(), | ||
} | ||
} | ||
|
||
export default handlers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export interface Color { | ||
id: string | ||
name: string | ||
color: string | ||
} | ||
|
||
export interface ColorCreateModel { | ||
name: string | ||
color: string | ||
} |
Oops, something went wrong.