Optis modelu danych bazuje na standardzie [JSONSchema](https://json-schema.org/specification.html) w wesji `draft-07` # Użycie `schema.json` ```JSON { "type": "object", "properties": { "imie": { // jeśli nie ma typu to przyjmuje domyślnie string "title": "Imię", "fieldRequired": true, "minLength": 3 }, "nazwisko": { "title": "Naziwsko", "type": "string", "fieldRequired": true, "minLength": 3 }, "nazwa": { "calc": "$methods.trim(this.imie + ' ' + this.naziwsko)" } } } ``` `App.vue` ```HTML ``` # Rozwinięcia ## `$ref` Pobranie schematu z definicji ```JSON "faktury": { "type": "array", "items": { "$ref" : "#/definitions/faktura" } }, "definitions": { "faktura": { "type": "object", "properties": { "netto": { "type": "money" }, "brutto": { "type": "money" } } } } ``` można używać jako schematu bazowego z połączeniem z `allOf` ```JSON "faktury": { "type": "array", "items": { "allOf": [ { "$ref" : "#/definitions/faktura" }, { "vat": { "type": "money" } } ] } } ``` ## `aggregate` Wartośc pola jest wyliczana na podstawie przeliczania tabeli ```JSON "aggregate": { "array": "kosztorys", // = this.kosztorys gdy nazwa jest prosta, dodawane jest this. na początku "property": "wartosc", // = $item.wartosc gdy występuje proste property to jest dodawane $item. na początku, jeśli jest pominięta agreguje po prostu elementy tablicy, np [1, 4, 67] "func": "sum", "when": "$item.cena>0" //tutaj trzeba pisać pełną nazwę pola, pola z bieżącego wiersza dostępne są poprzez $item, lub $array[$index] } ``` Dostępne funkcje: - `sum` - suma, domyślna funkcja gdy jej nie podano - `max` - wartość maksymalna - `min` - wartość minimalna - `avg` - średnia - `count` - liczba elementów, ma sens przy podaniu `when`, w innym przypadku lepiej użyć `calc` i `array.length` - `mul` - iloczyn - `first` - zwraca pierwszy element - `last` - zwraca ostatni element - `map` - zwraca talicę elementów Dostępne właściwości (do uzycia w `array`, `property` i `when`): - `this` - bieżący kontekst modelu, wlasciwosci która jest wyliczana - `$array` - aktualna tablica na której odbywa się agregacja - `$index` - aktualny indeks w tablicy - `$item` - aktualny element w tablicy, odpowiednik `$array[$index]` - `$root` - gałąź główna modelu - `$parent` - gałąz nadrzedna względem `this` - `$parent.$parent`, `$parent2` - gałąź modelu nadrzędna do `$parent` - `$parent.$parent.$parent`, `$parent3` - gałąź modelu nadrzędna do `$parent2` - `$obj` - bieżący obiekt schematu, dostepne pola typu `$schema`, `$key` i inne - `$methods` - metody matematyczne, na razie tylko `mround` do zaokrągleń Funkcja `when` jest wykonywana dla kadego elementu tablicy, spowalnia to znacznie wykonanie funkcji, uywac tylko w razie konieczności W `array` mozna skorzystać z `$root`, `$parent` i zewnętrznych danych z gałęzi `$external`. `array` moze byc tablica nazw, wtedy agregacji odbedzie sie po wielu talicach: ```JSON "aggreagte": { "array": ["kosztorys1", "kosztorys2"], "property": "brutto" } ``` jeśli nazwa tablicy zawiera znak `/` to jest przeprowadzane sumowanie pod podtablicy, czyli np. `kosztorys[0...].fakturydodatowe[]` ```JSON "aggreagte": { "array": "kosztorys/fakturydodatowe", "property": "brutto" } ``` W `property` równiez mozna skorzystac ze złozonych kalkulacji typu `$item.ilosc * $item.cena` ale znacznie spowalnia to wykonanie pętli wyliczającej, uzywac tylko w ramach koniecznosci. Lepiej wykonac dwa proste sumowania i pozniej policzyc iloraz. ## `allOf` Służy do łączenia wielu schematów, wg kolejności ich podania ```JSON "allOf": [ { "faktury": { "properties": { "netto": { "type": "money" } } } }, { "faktury": { "properties": { "brutto": { // dołożenie do faktur pola brutto "type": "money" } } } }, ] ``` ## `calc` Zawiera informacje o tym że wartośc pola jest wyliczana na podstawie innych pól, przykład: ```JSON "calc" : "this.ilosc * this.cena" ``` Dostępne właściwości `$root` `$parent` oraz wszystkie własciwosci z gałęzi `$external`, patrz `aggreagate` `this` jest wymagane w odwołaniach do pól `calc` może być podana jako obiekt: ```JSON "calc": { "func": "this.ilosc * this.cena", "when": "this.ilosc>0" } ``` gdy warunek `when` nie jest spełniony to model nie jest uzupełniany, czyli trzeba ręcznie wypełnić ## `computed` Ustawienie tej właściwości na `true` spowoduje, że pole to będzie tworzonena potrzeby interfejsu, a przy zapisie będzie to pole usuwane ```JSON "computed": true ``` ## `debug` _Tylko w trybie development_ Ustawienie tej wartości (w połączeniu z `calc` lub `aggregate`) powoduje, że Chrome zatrzyma się przed obliczeniem wartości tego pola w celu sprawdzenia poprawności obliczeń ## `enum` Pole musi przybrać jedną z podanych wartości ```JSON "enum": [1, 2, 3] //musi przyjąc wartośc 1 lub 2 lub 3 ``` ```JSON "enum": [true] // musi być true ``` ```JSON "enum": "[this.Koszt]" //musi być równe polu Koszt ``` ## `format` Dodatkowe formaty walidacji - `email` - mail - `nip` - sprawdza prawidłowość numeru NIP - `pesel` - poprawność PESEL - `regon` - poprawność REGON - `iban` / `nrb` - numer konta - `dowod` - numer dowodu - `data-time` - data i czas `yyyy-MM-dd HH:mm:ss`, lub RFC JSON - `date` - sama data `yyyy-MM-dd` - `kod` - kod pocztowy - `numeric` - tylko cyfry ## `length` Pilnuje długości tablicy, można być wyliczane na podstawie innych pól ## `minimum` Minimalna wartość, `number` ## ~~`summary`~~ - wycofane, patrz `aggregate` Wartośc pola jest wyliczana na podstawie podsumowania tabeli ```JSON "summary": { "array": "kosztorys", "property": "wartosc" } ``` W `array` mozna skorzystac z `$root`, `$parent` i zewnętrznych danych z gałęzi `external` ## `type` - `string` - tekst - `integer` - całkowita - `number` - zmiennoprzecinkowa - `money` - automatycznie zaokrągla do 2 miejsc po przecinku - `boolean` - `true`/`false` ## `validationMessages` Komunikaty walidacji, według klucza, przykład: ```JSON "validationMessages": { "required": "Pole XXX jest wymagane", "type": "Nieprawidłowy typ danych", "minimum": "Wartość musi być większa niż 10", "validFunc": "Wartośc musi być większa niz w konkursie" } ``` można używać zmiennych w komuniakcie, poza tymi z walidacji dostępne jest `value` ```JSON "validationMessages": { "minimum": "Wartość musi być większa niż {{minimum}}, a wynosi {{value}}" } ``` ## `validFunc` Dowolna funkcja do walidacji ```JSON "validFunc": "$value>=$external.$konkurs.minValue" ``` Mozliwość koszystania z właściwości `$root` `$parent` oraz wszystkich własciwosci z gałęzi `$external`. `$value` oznacza bierzącą wartość pola, pozostałe wartości identyczne jak w `aggreagte` Bardziej złozne funkcje muszą być otoczone klamrą: ```JSON "validFunc": "{if ($value>0) return \"za mało\"}" ``` - `true` - wszystko ok, zwraca `null` - `false` - zwraca `validFunc` - `null` - wszystko ok - niepusty tekst - zwraca ten tekst jako komunikat błędu ## `$methods` Metody których można używać w funkcjach wyliczeniowych, agregacyjnych i walidacyjnych, np. `$methods.mround(this.Kwota)` - `mround`: funkcja zaokrąglenia do określonej liczny miejsc po przecinku, domyślnie do 2 ```TypeScript mround(value: number, precision: number = 2): number ``` - `fmoney`: formatowanie wartości liczbowych, `forceZeros` oznacza że zawsze będzie określona liczba miejsc po przecinku ```TypeScript fmoney(value: number, forcezeros?: boolean, precision: number = 2): string ``` - `fdate`: formatowanie daty do formatu `yyyy-MM-dd` ```TypeScript fdate(dt: Date): string ``` - `ftime`: formatowanie czasu do formatu `HH:mm:ss` ```TypeScript ftime(dt: Date): string ``` - `fdatetime`: formatowanie daty i czasu do formatu `yyyy-MM-dd HH:mm:ss` ```TypeScript fdatetime(dt: Date) : string ``` - `padNumber`: dodanie brakujących zer przed liczbą, domyślnie wyrównuje do 2 znaków ```TypeScript padNumber(value: number, minLength: number = 2) : string ``` - `dateDiff`: oblicznenie różnicy dat, zwraca obiekt `TimeSpan` określający różnicę w datach, np. `dateDiff(this.DateEnd,this.DateStart).days` ```TypeScript dateDiff(lateDate: string, earlyDate: string): TimeSpan class TimeSpan { totalMiliseconds: number; //całkowita liczba milisekund miliseconds: number; //liczba milisekund po odjęciu sekund, minut, godzin i dni totalSeconds: number; //całkowita liczba sekund = totalMiliseconds/1000 seconds: number; //liczba sekund po odjęciu minut, godzin i dni totalMinutes: number; //całkowita liczba minut = totalSceconds/60 minutes: number; //liczba minut po odjęciu godzin i dni totalHours: number; //całkowita liczba godzin = totalMinutes/60 hours: number; //liczba godzn po odjęciu liczby dni totalDays: number; //całkowita liczba dni = totalHours/24 days: number; //całkowita liczba dni, zaokrąglona w dół do płenych dni months: number; //liczba miesięcy, wartośc całkowita toString(): string; //różnica w postaci HH:mm:ss } ``` - `today`: dziś, w formacie `yyyy-MM-dd` ```TypeScript today() : string ``` - `now`: teraz, w formacie `yyyy-MM-dd HH:mm:ss` ```TypeScript now() : string ``` - `guid`: oblicza nowy guid ```TypeScript guid() : string ``` - `check`: sprawdza format tekstu, np. `check('nip',this.Nip)` ```TypeScript check(format: string, value: string) : boolean ``` - `datePart`: zwraca określone pole z daty. np. `datePart(this.DateStart,'d')` ```TypeScript datePart(date: string, part: string): number wartości part: 'd' - dzień 'M' - miesiąc 'y' - rok 'h' - godzina 'm' - minuta 's' - sekunda ``` - `dateAdd`: dodaje do daty określoną liczbę jednostek, np. `dateAdd(this.DateStart,'d',7)` ```TypeScript dateAdd(date: string, part: string, value: number) : string // wartości part identyczne jak w datePart() ``` - `dateSet`: ustawia w dacie odpowiednią część, np. `dateSet(this.DateStart,'d',7)` ```TypeScript dateSet(date: string, part: string, value: number) : string // wartości part identyczne jak w datePart() ``` - `dateParse`: zamienia datę w formacie `yyyy-MM-dd` lub `yyyy-MM-dd HH:mm:ss` ```TypeScript dateParse(date: string) : Date ``` - `max`: oblicza maksymalną wartośc z tablicy, np. `max(['2019-01-01','2019-05-01'])` ```TypeScript max(values: any[]) : any ``` - `min` oblicza minimalną wartośc z tablicy, np. `min(['2019-01-01','2019-05-01'])` ```TypeScript min(values: any[]) : any ``` - `listMonths`: lista miesięcy pomiędzy datami ```TypeScript listMonths(startDate: string, endDate: string, format?: string/* = 'MMMM yyyy'*/): string[] ``` - `listYears`: lista lat pomiędzy datami ```TypeScript listYears(startDate: string, endDate: string): number[] ``` - `trim`: obcina spacje w tekscie ```TypeScript trim(text: string): string ``` # funkcje na $schema obj (czyli na dowolnym polu obudowanego schematu) ## `$dirtyList()` - zwaraca listę pól ze statusem `$dirty === true` ## `$setData(value: any, path?: string, fixArraySize?: boolean)` - ustawienie wartości pola - `path` - ustawia pole wg podenej ścieżki nazwy - `fixArraySize` - w przypadku tabel zmienia ich rozmiar na ten podany w `value` ## `$reset()` - czyściu status `$dirty` i `$errors`, na elemencie oraz wszystkich dzieci ## `$validate()` - waliduje pole, ustawia status `$dirty` na true ## `$validateAll()` - waliduje pole i wszystkie dzieci ustawia status `$dirty` na true # funkcje na $schema - tylko tablice ## `$addRow(nvalue: any, count: number = 1)` - dodaje wiersza do tabeli, `nvalue` to wartośc nowo dodanego wiersza - `count` można dodać więcej wierszy niż 1 ## `$removeRow(index)` - usuwa wiersz o indeksie `index` ## `$clearRow(index)` - czyści wiersz o indeksie `index` - wstawia domyślne wartości ## `$exchangeRow(index1: number, index2: number)` - zamienia wiersz miejscami ## `$moveUp(index: number)` - przesuwa wiersz w górę ## `$moveDown(index: number)` - przesuwa wiersz w dół ## `$sort(field: string)` - sortuje tablicę wg podanego pola ## `$filter(func: (value: any, index: number, array: any[]) => boolean)` - zwraca elementy tablicy spełniające funkcję ## `$getItems(start?: number, count?: number)` - zwraca wycinek tablicy - `start` - domyślnie 0 - `count` - domyślnie `pageSize`, domyslnie ## `$getPage(page: number, pageSize: number = 25)` - pobiera kolejną stronę ## `pageNumber` - bierząca strona ## `pageSize` - rozmiar strony ## `pageCount` - liczba stron ## `order` - aktualne sortowanie