Skip to content
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
24 changes: 19 additions & 5 deletions src/app/src/components/shared/item/ItemCardForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,21 @@ const schema = computed(() => z.object({
extension: z.enum([...CONTENT_EXTENSIONS, ...MEDIA_EXTENSIONS] as [string, ...string[]]).nullish(),
prefix: z.preprocess(
val => val === '' ? null : val,
z.number().int().positive().nullish(),
z.string()
.regex(/^\d+$/, 'Prefix must be a string containing only digits')
.refine(
(prefix: string | null | undefined) => {
if (prefix === null || prefix === undefined) {
return true
}

const num = Number(prefix)

return Number.isInteger(num) && num >= 0
},
'Prefix must be a non-negative integer',
)
.nullish(),
),
}).refine(() => {
const siblings = props.parentItem.children?.filter(child => !child.hide) || []
Expand All @@ -87,7 +101,7 @@ const schema = computed(() => z.object({
type Schema = {
name: string
extension: string | null | undefined
prefix: number | null | undefined
prefix: string | null | undefined
}
const state = reactive<Schema>({
name: originalName.value,
Expand Down Expand Up @@ -267,11 +281,11 @@ async function onSubmit() {
<span />
</template>
<UInput
v-model.number="state.prefix"
type="number"
v-model="state.prefix"
type="text"
pattern="[0-9]*"
variant="soft"
placeholder="N°"
min="1"
class="h-5"
size="xs"
:disabled="isLoading"
Expand Down
2 changes: 1 addition & 1 deletion src/app/src/types/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface TreeItem {
name: string
fsPath: string // unique identifier
type: 'file' | 'directory' | 'root'
prefix: number | null
prefix: string | null
status?: TreeStatus
routePath?: string
children?: TreeItem[]
Expand Down
4 changes: 2 additions & 2 deletions src/app/src/utils/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ export const FILE_ICONS = {
...AUDIO_EXTENSIONS.reduce((acc, ext) => ({ ...acc, [ext]: 'i-lucide-file-audio' }), {}),
}

export function parseName(name: string): { name: string, prefix: number | null, extension: string | null } {
export function parseName(name: string): { name: string, prefix: string | null, extension: string | null } {
const prefixMatch = name.match(/^(\d+)\./)
const extensionMatch = name.match(/\.(\w+)$/)
return {
prefix: prefixMatch ? Number.parseInt(prefixMatch[1], 10) : null,
prefix: prefixMatch ? prefixMatch[1] : null,
extension: extensionMatch ? extensionMatch[1] : null,
name: name.replace(/^\d+\./, ''),
}
Expand Down
10 changes: 5 additions & 5 deletions src/app/test/mocks/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,34 @@ export const tree: TreeItem[] = [
name: 'getting-started',
fsPath: '1.getting-started',
type: 'directory',
prefix: 1,
prefix: '1',
children: [
{
name: 'introduction',
fsPath: '1.getting-started/2.introduction.md',
type: 'file',
routePath: '/getting-started/introduction',
prefix: 2,
prefix: '2',
},
{
name: 'installation',
fsPath: '1.getting-started/3.installation.md',
type: 'file',
routePath: '/getting-started/installation',
prefix: 3,
prefix: '3',
},
{
name: 'advanced',
fsPath: '1.getting-started/1.advanced',
type: 'directory',
prefix: 1,
prefix: '1',
children: [
{
name: 'studio',
fsPath: '1.getting-started/1.advanced/1.studio.md',
type: 'file',
routePath: '/getting-started/installation/advanced/studio',
prefix: 1,
prefix: '1',
},
],
},
Expand Down
28 changes: 14 additions & 14 deletions src/app/test/unit/utils/tree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ describe('buildTree of documents with one level of depth', () => {
name: 'getting-started',
fsPath: '1.getting-started',
type: 'directory',
prefix: 1,
prefix: '1',
children: [
{
name: 'introduction',
fsPath: '1.getting-started/2.introduction.md',
type: 'file',
routePath: '/getting-started/introduction',
prefix: 2,
prefix: '2',
},
{
name: 'installation',
fsPath: '1.getting-started/3.installation.md',
type: 'file',
routePath: '/getting-started/installation',
prefix: 3,
prefix: '3',
},
],
},
Expand Down Expand Up @@ -97,7 +97,7 @@ describe('buildTree of documents with one level of depth', () => {
type: 'file',
routePath: deletedDbItem.path,
status: TreeStatus.Deleted,
prefix: 2,
prefix: '2',
},
],
},
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('buildTree of documents with one level of depth', () => {
type: 'file',
routePath: deletedDbItem.path,
status: TreeStatus.Deleted,
prefix: 3,
prefix: '3',
},
],
},
Expand Down Expand Up @@ -282,7 +282,7 @@ describe('buildTree of documents with one level of depth', () => {
name: createdDbItem.path!.split('/').pop()!,
type: 'file',
status: TreeStatus.Renamed,
prefix: 2,
prefix: '2',
},
],
},
Expand All @@ -296,27 +296,27 @@ describe('buildTree of documents with two levels of depth', () => {
name: 'essentials',
fsPath: '1.essentials',
type: 'directory',
prefix: 1,
prefix: '1',
children: [
{
name: 'configuration',
fsPath: '1.essentials/2.configuration.md',
type: 'file',
routePath: '/essentials/configuration',
prefix: 2,
prefix: '2',
},
{
name: 'nested',
fsPath: '1.essentials/1.nested',
type: 'directory',
prefix: 1,
prefix: '1',
children: [
{
name: 'advanced',
fsPath: '1.essentials/1.nested/2.advanced.md',
type: 'file',
routePath: '/essentials/nested/advanced',
prefix: 2,
prefix: '2',
},
],
},
Expand Down Expand Up @@ -424,7 +424,7 @@ describe('buildTree of documents with two levels of depth', () => {
routePath: deletedDbItem.path,
type: 'file',
status: TreeStatus.Deleted,
prefix: 2,
prefix: '2',
},
],
},
Expand Down Expand Up @@ -452,21 +452,21 @@ describe('buildTree of documents with language prefixed', () => {
name: 'getting-started',
fsPath: 'en/1.getting-started',
type: 'directory',
prefix: 1,
prefix: '1',
children: [
{
name: 'introduction',
fsPath: 'en/1.getting-started/2.introduction.md',
type: 'file',
routePath: '/en/getting-started/introduction',
prefix: 2,
prefix: '2',
},
{
name: 'installation',
fsPath: 'en/1.getting-started/3.installation.md',
type: 'file',
routePath: '/en/getting-started/installation',
prefix: 3,
prefix: '3',
},
],
},
Expand Down
Loading