fix: date

This commit is contained in:
opbnq-q
2025-03-08 04:21:35 -08:00
parent 882ba30792
commit 479a4e11ec
25 changed files with 5622 additions and 58 deletions

View File

@@ -5,9 +5,6 @@
// @ts-ignore: Unused imports // @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime"; import {Create as $Create} from "@wailsio/runtime";
/**
* Author A sample of comment
*/
export class Author { export class Author {
"Id": number; "Id": number;
"Name": string; "Name": string;

3542
frontend/dist/assets/index-AV0W6jam.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title> <title>Vite + Vue + TS</title>
<script type="module" crossorigin src="/assets/index-DsBrcYCq.js"></script> <script type="module" crossorigin src="/assets/index-AV0W6jam.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BnDWzbnJ.css"> <link rel="stylesheet" crossorigin href="/assets/index-BQIDz5Af.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@@ -9,8 +9,10 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@primevue/themes": "^4.2.5", "@primevue/themes": "^4.2.5",
"@wailsio/runtime": "3.0.0-alpha.66",
"pinia": "^2.3.0", "pinia": "^2.3.0",
"primeicons": "^7.0.0", "primeicons": "^7.0.0",
"primelocale": "^2.0.3",
"primevue": "^4.2.5", "primevue": "^4.2.5",
"vue": "^3.5.13" "vue": "^3.5.13"
}, },
@@ -1188,6 +1190,12 @@
} }
} }
}, },
"node_modules/@wailsio/runtime": {
"version": "3.0.0-alpha.66",
"resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.66.tgz",
"integrity": "sha512-ENLu8rn1griL1gFHJqkq1i+BVxrrA0JPJHYneUJYuf/s54kjuQViW0RKDEe/WTDo56ABpfykrd/T8OYpPUyXUw==",
"license": "MIT"
},
"node_modules/alien-signals": { "node_modules/alien-signals": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.4.tgz", "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.4.tgz",
@@ -2322,6 +2330,16 @@
"integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==", "integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/primelocale": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/primelocale/-/primelocale-2.0.3.tgz",
"integrity": "sha512-/sMoTdLxDFJs2Bdns+F4lm33ph6m4j18Rho8y9dsz5DqgWliqXsfYu1We4tkHtviRWq8AzEj31TDLDA3NEYC0Q==",
"license": "MIT",
"engines": {
"node": ">=18.0.0",
"npm": ">=8.6.0"
}
},
"node_modules/primevue": { "node_modules/primevue": {
"version": "4.3.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/primevue/-/primevue-4.3.1.tgz", "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.3.1.tgz",

View File

@@ -10,8 +10,10 @@
}, },
"dependencies": { "dependencies": {
"@primevue/themes": "^4.2.5", "@primevue/themes": "^4.2.5",
"@wailsio/runtime": "3.0.0-alpha.66",
"pinia": "^2.3.0", "pinia": "^2.3.0",
"primeicons": "^7.0.0", "primeicons": "^7.0.0",
"primelocale": "^2.0.3",
"primevue": "^4.2.5", "primevue": "^4.2.5",
"vue": "^3.5.13" "vue": "^3.5.13"
}, },

1869
frontend/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,5 +4,7 @@ import PostScheme from './post/PostScheme.vue';
</script> </script>
<template> <template>
<main class="w-screen h-screen">
<PostScheme /> <PostScheme />
</main>
</template> </template>

View File

@@ -0,0 +1,40 @@
<script setup lang="ts">
import Table from '../table/Table.vue'
import { onMounted, reactive } from 'vue'
import { getDefaultValues } from '../utils/structs/defaults.util.ts'
import S from './author.service.ts'
import type { Scheme } from '../types/scheme.type'
import { Author } from '../../bindings/app/internal/services/models.ts'
const service = new S
onMounted(async () => {
})
const scheme: Scheme<Author> = reactive({
Id:{
hidden: true,
type: {
primitive: "number",
},
},
Name:{
russian: "Имя",
type: {
primitive: "string",
},
},
})
const getDefaults = () => getDefaultValues(scheme)
</script>
<template>
<main class="w-screen h-screen">
<Table :scheme :service :getDefaults></Table>
</main>
</template>

View File

@@ -0,0 +1,29 @@
import { GetAll, Create, Delete, GetById, Update, Count } from "../../bindings/app/internal/services/authorservice.ts"
import type { Author } from "../../bindings/app/internal/services/models.ts"
import type { IService } from "../types/service.type.ts"
export default class AuthorService implements IService<Author> {
async read(id: number) {
return await GetById(id) as Author
}
async readAll() {
return await GetAll() as Author[]
}
async create(item: Author) {
await Create(item)
}
async delete(id: number) {
return await Delete(id)
}
async update(item: Author) {
await Update(item)
}
async count() {
return await Count()
}
}

View File

@@ -4,9 +4,11 @@ import App from './App.vue'
import { Config } from 'primevue' import { Config } from 'primevue'
import Aura from '@primevue/themes/aura' import Aura from '@primevue/themes/aura'
import 'primeicons/primeicons.css' import 'primeicons/primeicons.css'
import { ru } from 'primelocale/js/ru.js'
createApp(App).use(Config, { createApp(App).use(Config, {
theme: { theme: {
preset: Aura preset: Aura,
} },
locale: ru
}).mount('#app') }).mount('#app')

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import Table from '../table/Table.vue' import Table from '../table/Table.vue'
import { onMounted, reactive } from 'vue' import { onMounted, reactive } from 'vue'
import { getDefaultValues } from '../utils/structs/defaults.util' import { getDefaultValues } from '../utils/structs/defaults.util.ts'
import S from './post.service.ts' import S from './post.service.ts'
import type { Scheme } from '../types/scheme.type' import type { Scheme } from '../types/scheme.type'
import { Post } from '../../bindings/app/internal/services/models.ts' import { Post } from '../../bindings/app/internal/services/models.ts'
@@ -15,22 +15,23 @@ onMounted(async () => {
const scheme: Scheme<Post> = reactive({ const scheme: Scheme<Post> = reactive({
Id: { Id: {
hidden: true,
type: { type: {
primitive: "number", primitive: "number",
}, },
hidden: true,
}, },
Text: { Text: {
russian: "Текст",
type: { type: {
primitive: "string", primitive: "string",
}, },
}, },
CreatedAt: { CreatedAt: {
hidden: true,
type: { type: {
primitive: "number", primitive: "number",
}, },
}, },
}) })
const getDefaults = () => getDefaultValues(scheme) const getDefaults = () => getDefaultValues(scheme)

View File

@@ -4,7 +4,7 @@ import type { IService } from "../types/service.type.ts"
export default class PostService implements IService<Post> { export default class PostService implements IService<Post> {
async read(id: number) { async read(id: number) {
return await GetById(id) return await GetById(id) as Post
} }
async readAll() { async readAll() {
@@ -18,9 +18,11 @@ export default class PostService implements IService<Post> {
async delete(id: number) { async delete(id: number) {
return await Delete(id) return await Delete(id)
} }
async update(item: Post) { async update(item: Post) {
await Update(item) await Update(item)
} }
async count() { async count() {
return await Count() return await Count()
} }

View File

@@ -1,3 +1,14 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
html, body {
background: white;
}
@media (prefers-color-scheme: dark) {
html, body {
background: #121212;
}
}

View File

@@ -5,10 +5,10 @@ import type { Scheme } from '../types/scheme.type';
import type { IService } from '../types/service.type'; import type { IService } from '../types/service.type';
import { manyStructsView } from '../utils/structs/structs-view.util'; import { manyStructsView } from '../utils/structs/structs-view.util';
import { type UnwrapRef } from 'vue'; import { type UnwrapRef } from 'vue';
import { toDate, toTimestamp } from '../utils/date/converters.util';
const showCreate = defineModel<boolean>('show') const showCreate = defineModel<boolean>('show')
const createItem = defineModel<T>('item') const createItem = defineModel<T>('item')
const items = defineModel<UnwrapRef<T[]>>('items') const items = defineModel<UnwrapRef<T[]>>('items')
const props = defineProps<{ const props = defineProps<{
@@ -45,7 +45,10 @@ const emits = defineEmits<{
v-else-if="props.scheme[key]?.type?.primitive === 'number'" /> v-else-if="props.scheme[key]?.type?.primitive === 'number'" />
<InputText class="w-[300px]" v-model:model-value="<string>createItem![key]" <InputText class="w-[300px]" v-model:model-value="<string>createItem![key]"
v-else-if="props.scheme[key].type?.primitive === 'string'" /> v-else-if="props.scheme[key].type?.primitive === 'string'" />
<DatePicker class="w-[300px]" v-model:model-value="<Date>createItem![key]" <DatePicker class="w-[300px]" :default-value="toDate(createItem![key] as number)" @value-change="v => {
createItem![key] = toTimestamp(v as Date) as any
console.log(createItem![key])
}" show-time
v-else-if="props.scheme[key].type?.primitive === 'date'" /> v-else-if="props.scheme[key].type?.primitive === 'date'" />
<Textarea class="w-[300px]" v-model="<string>createItem![key]" <Textarea class="w-[300px]" v-model="<string>createItem![key]"
v-else-if="props.scheme[key].type?.primitive === 'multiple'" /> v-else-if="props.scheme[key].type?.primitive === 'multiple'" />
@@ -76,12 +79,12 @@ const emits = defineEmits<{
</div> </div>
<template #footer> <template #footer>
<Button severity="success" @click="async () => { <Button severity="success" @click="async () => {
console.log(createItem)
if (props.updateMode) { if (props.updateMode) {
await props.service.update(createItem as T) await props.service.update(createItem as T)
await emits('onSaveUpdate', createItem as T) await emits('onSaveUpdate', createItem as T)
await emits('onSave', createItem as T) await emits('onSave', createItem as T)
} else { } else {
if (createItem) createItem.Id = 0;
await props.service.create(createItem as T) await props.service.create(createItem as T)
await emits('onSaveCreate', createItem as T) await emits('onSaveCreate', createItem as T)
await emits('onSave', createItem as T) await emits('onSave', createItem as T)

View File

@@ -7,6 +7,8 @@ import type { TableEmits } from "../types/table-emits.type";
import FloatingButton from "../components/buttons/FloatingButton.vue"; import FloatingButton from "../components/buttons/FloatingButton.vue";
import type { IEntity } from "../types/entity.type"; import type { IEntity } from "../types/entity.type";
import DialogWindow from "./DialogWindow.vue"; import DialogWindow from "./DialogWindow.vue";
import { timestampToDate } from "../utils/date/converters.util";
import { viewDate } from "../utils/date/view.util";
const props = defineProps<TableProps<T>>(); const props = defineProps<TableProps<T>>();
@@ -116,10 +118,10 @@ const updateSlotName = (key: any) => key + "Update";
<template #body="{ data }"> <template #body="{ data }">
<p> <p>
{{ {{
manyStructsView( viewDate(manyStructsView(
data[key], data[key],
props.scheme[key]?.type?.nested?.field, props.scheme[key]?.type?.nested?.field,
) ), scheme[key]?.type?.primitive)
}} }}
</p> </p>
</template> </template>
@@ -131,9 +133,9 @@ const updateSlotName = (key: any) => key + "Update";
<Button <Button
severity="secondary" severity="secondary"
icon="pi pi-pencil" icon="pi pi-pencil"
@click="() => { @click="async () => {
emits('onUpdateOpen') await emits('onUpdateOpen')
emits('onOpen') await emits('onOpen')
updateItem = data updateItem = data
}" }"
></Button> ></Button>
@@ -141,7 +143,7 @@ const updateSlotName = (key: any) => key + "Update";
severity="danger" severity="danger"
icon="pi pi-trash" icon="pi pi-trash"
@click="async () => { @click="async () => {
emits('onDelete', data) await emits('onDelete', data)
await props.service.delete(data.Id) await props.service.delete(data.Id)
items = await props.service.readAll() as UnwrapRef<T[]> items = await props.service.readAll() as UnwrapRef<T[]>
}" }"

View File

@@ -1,4 +1,4 @@
const getFullTimestamp = (n: number): number => { export const getFullTimestamp = (n: number): number => {
const length = String(n).length const length = String(n).length
let str = '' let str = ''
while (str.length + length < 13) { while (str.length + length < 13) {
@@ -6,5 +6,34 @@ const getFullTimestamp = (n: number): number => {
} }
return parseInt(`${n}${str}`) return parseInt(`${n}${str}`)
} }
export const toDate = (n: number) => new Date(getFullTimestamp(n)) export const toDate = (n: number | Date) => {
if (n instanceof Date) return n
return new Date(getFullTimestamp(n))
}
export const toTimestamp = (d: Date) => d.getTime() export const toTimestamp = (d: Date) => d.getTime()
export const dateToTimestamp = (obj: any) => {
if (typeof obj == 'object') {
for (let key in obj) {
if (obj[key] instanceof Date) {
obj[key] = toTimestamp(obj[key])
} else if (typeof obj[key] == 'object') {
dateToTimestamp(obj[key])
}
}
}
return obj
}
export const timestampToDate = (obj: any) => {
if (typeof obj == 'object') {
for (let key in obj) {
if (typeof obj[key] == 'number') {
obj[key] = toDate(obj[key])
} else if (typeof obj[key] == 'object') {
timestampToDate(obj[key])
}
}
}
return obj
}

View File

@@ -0,0 +1,14 @@
import type { PrimitiveFieldType } from "../../types/primitive-field-type.type"
import { toDate } from "./converters.util";
export const viewDate = (data: unknown, type: PrimitiveFieldType) => {
if (type !== 'date') return data;
return toDate(data as number | Date).toLocaleDateString('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})
}

View File

@@ -1,6 +1,6 @@
import type { IEntity } from "../../types/entity.type"; import type { IEntity } from "../../types/entity.type";
import type { Scheme } from "../../types/scheme.type"; import type { Scheme } from "../../types/scheme.type";
import { getTomorrow } from "../date/getters"; import { toTimestamp } from "../date/converters.util";
export const getDefaultValues = <T extends IEntity>(scheme: Scheme<T>) => { export const getDefaultValues = <T extends IEntity>(scheme: Scheme<T>) => {
const keys = Object.keys(scheme) as (keyof typeof scheme)[] const keys = Object.keys(scheme) as (keyof typeof scheme)[]
@@ -8,10 +8,11 @@ export const getDefaultValues = <T extends IEntity>(scheme: Scheme<T>) => {
for (let key of keys) { for (let key of keys) {
const primitive = scheme[key]?.type?.primitive const primitive = scheme[key]?.type?.primitive
if (primitive == 'string' || primitive == 'multiple') { if (scheme[key].hidden) continue;
if ((primitive == 'string' || primitive == 'multiple')) {
obj[key] = '' obj[key] = ''
} else if (primitive == 'date') { } else if (primitive == 'date') {
obj[key] = getTomorrow() obj[key] = toTimestamp(new Date)
} else if (primitive == 'boolean') { } else if (primitive == 'boolean') {
obj[key] = false obj[key] = false
} else if (primitive == 'number') { } else if (primitive == 'number') {

View File

@@ -5,11 +5,11 @@
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"noEmit": true, "noEmit": true,
/* Linting */ /* Linting */
"strict": true, "strict": false,
"noUnusedLocals": true, "noUnusedLocals": false,
"noUnusedParameters": true, "noUnusedParameters": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": false,
"noUncheckedSideEffectImports": true, "noUncheckedSideEffectImports": false,
"lib": ["ES2015", "DOM"] "lib": ["ES2015", "DOM"]
}, },
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],

View File

@@ -14,11 +14,11 @@
"noEmit": true, "noEmit": true,
/* Linting */ /* Linting */
"strict": true, "strict": false,
"noUnusedLocals": true, "noUnusedLocals": false,
"noUnusedParameters": true, "noUnusedParameters": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": false,
"noUncheckedSideEffectImports": true "noUncheckedSideEffectImports": false
}, },
"include": ["vite.config.ts"] "include": ["vite.config.ts"]
} }

View File

@@ -36,7 +36,6 @@ func main() {
Backdrop: application.MacBackdropTranslucent, Backdrop: application.MacBackdropTranslucent,
TitleBar: application.MacTitleBarHiddenInset, TitleBar: application.MacTitleBarHiddenInset,
}, },
BackgroundColour: application.NewRGB(27, 38, 54),
URL: "/", URL: "/",
}) })
dialogs.Init(window) dialogs.Init(window)

Submodule nto-cli updated: 2fd8b20b77...c9a3a654dd

BIN
wails_windows_amd64.syso Normal file

Binary file not shown.