fuma 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/private/Meta.svelte +27 -32
  2. package/dist/private/Meta.svelte.d.ts +0 -1
  3. package/dist/private/api.d.ts +1 -1
  4. package/dist/ui/badge/Badge.svelte +3 -4
  5. package/dist/ui/button/ButtonCopy.svelte +31 -37
  6. package/dist/ui/button/ButtonDelete.svelte +21 -23
  7. package/dist/ui/button/ButtonDelete.svelte.d.ts +0 -1
  8. package/dist/ui/card/Card.svelte +10 -13
  9. package/dist/ui/card/Card.svelte.d.ts +0 -1
  10. package/dist/ui/card/CardBasic.svelte +4 -5
  11. package/dist/ui/card/CardBasic.svelte.d.ts +0 -1
  12. package/dist/ui/card/CardCollapse.svelte +31 -35
  13. package/dist/ui/card/CardCollapse.svelte.d.ts +0 -1
  14. package/dist/ui/card/CardFullScreen.svelte +6 -8
  15. package/dist/ui/card/CardFullScreen.svelte.d.ts +0 -3
  16. package/dist/ui/card/CardLink.svelte +4 -5
  17. package/dist/ui/card/CardLink.svelte.d.ts +0 -1
  18. package/dist/ui/dialog/Dialog.svelte +34 -41
  19. package/dist/ui/dialog/Dialog.svelte.d.ts +0 -1
  20. package/dist/ui/dialog/DialogConfirm.svelte +4 -6
  21. package/dist/ui/dialog/DialogConfirm.svelte.d.ts +0 -1
  22. package/dist/ui/drawer/Drawer.svelte +37 -46
  23. package/dist/ui/drawer/Drawer.svelte.d.ts +0 -16
  24. package/dist/ui/form/Form.svelte +82 -100
  25. package/dist/ui/form/Form.svelte.d.ts +0 -1
  26. package/dist/ui/form/FormInput.svelte +6 -12
  27. package/dist/ui/form/FormInput.svelte.d.ts +0 -18
  28. package/dist/ui/form/FormSection.svelte +16 -23
  29. package/dist/ui/form/formInput.d.ts +0 -1
  30. package/dist/ui/icon/Icon.svelte +32 -35
  31. package/dist/ui/input/FormControl.svelte +32 -38
  32. package/dist/ui/input/FormControl.svelte.d.ts +0 -3
  33. package/dist/ui/input/InputBoolean.svelte +8 -13
  34. package/dist/ui/input/InputBoolean.svelte.d.ts +0 -3
  35. package/dist/ui/input/InputCheckboxs.svelte +20 -22
  36. package/dist/ui/input/InputCheckboxs.svelte.d.ts +0 -3
  37. package/dist/ui/input/InputCheckboxsMenu.svelte +35 -51
  38. package/dist/ui/input/InputCheckboxsMenu.svelte.d.ts +0 -3
  39. package/dist/ui/input/InputCheckboxsTree.svelte +6 -9
  40. package/dist/ui/input/InputCheckboxsTreeNodes.svelte +27 -35
  41. package/dist/ui/input/InputCombo.svelte +34 -43
  42. package/dist/ui/input/InputCombo.svelte.d.ts +0 -3
  43. package/dist/ui/input/InputDate.svelte +17 -22
  44. package/dist/ui/input/InputDateTime.svelte +18 -23
  45. package/dist/ui/input/InputImage.svelte +45 -52
  46. package/dist/ui/input/InputImage.svelte.d.ts +0 -1
  47. package/dist/ui/input/InputImagePreview.svelte +20 -24
  48. package/dist/ui/input/InputNumber.svelte +5 -10
  49. package/dist/ui/input/InputOptionInParam.svelte +10 -12
  50. package/dist/ui/input/InputOptions.svelte +34 -40
  51. package/dist/ui/input/InputPassword.svelte +5 -7
  52. package/dist/ui/input/InputPassword.svelte.d.ts +0 -3
  53. package/dist/ui/input/InputRadio.svelte +32 -36
  54. package/dist/ui/input/InputRadio.svelte.d.ts +0 -3
  55. package/dist/ui/input/InputRelation.svelte +67 -83
  56. package/dist/ui/input/InputRelation.svelte.d.ts +0 -1
  57. package/dist/ui/input/InputRelations.svelte +79 -92
  58. package/dist/ui/input/InputSearch.svelte +10 -13
  59. package/dist/ui/input/InputSelect.svelte +28 -39
  60. package/dist/ui/input/InputText.svelte +7 -8
  61. package/dist/ui/input/InputTextarea.svelte +6 -6
  62. package/dist/ui/input/InputTime.svelte +23 -29
  63. package/dist/ui/input/RelationAfter.svelte +9 -13
  64. package/dist/ui/input/SelectorList.svelte +12 -16
  65. package/dist/ui/input/SelectorList.svelte.d.ts +0 -4
  66. package/dist/ui/input/textRich/InputTextRich.svelte +50 -52
  67. package/dist/ui/input/textRich/InputTextRich.svelte.d.ts +9 -3
  68. package/dist/ui/input/textRich/SuggesionList.svelte +9 -13
  69. package/dist/ui/input/textRich/ToolMark.svelte +9 -12
  70. package/dist/ui/input/textRich/ToolMarkColor.svelte +11 -15
  71. package/dist/ui/input/textRich/ToolMarkLink.svelte +38 -46
  72. package/dist/ui/input/textRich/ToolMenu.svelte +19 -34
  73. package/dist/ui/input/textRich/ToolMenuAlign.svelte +9 -13
  74. package/dist/ui/input/textRich/ToolMenuInsert.svelte +7 -12
  75. package/dist/ui/input/textRich/ToolMenuNode.svelte +10 -14
  76. package/dist/ui/input/textRich/ToolsBar.svelte +11 -15
  77. package/dist/ui/login/Login.svelte +30 -36
  78. package/dist/ui/menu/ContextMenu.svelte +31 -37
  79. package/dist/ui/menu/ContextMenu.svelte.d.ts +0 -1
  80. package/dist/ui/menu/DropDown.svelte +83 -92
  81. package/dist/ui/menu/DropDown.svelte.d.ts +0 -1
  82. package/dist/ui/menu/DropDownMenu.svelte +18 -25
  83. package/dist/ui/menu/DropDownMenu.svelte.d.ts +0 -1
  84. package/dist/ui/mode/ToggleMode.svelte +14 -15
  85. package/dist/ui/mode/ToggleMode.svelte.d.ts +1 -6
  86. package/dist/ui/pagination/Pagination.svelte +8 -9
  87. package/dist/ui/placeholder/Placeholder.svelte +3 -4
  88. package/dist/ui/placeholder/Placeholder.svelte.d.ts +0 -1
  89. package/dist/ui/placeholder/PlaceholderImage.svelte +4 -6
  90. package/dist/ui/placeholder/PlaceholderImage.svelte.d.ts +0 -1
  91. package/dist/ui/range/RangePicker.svelte +62 -75
  92. package/dist/ui/range/RangePicker.svelte.d.ts +2 -2
  93. package/dist/ui/range/RangePickerButton.svelte +35 -43
  94. package/dist/ui/slot/Slot.svelte +25 -42
  95. package/dist/ui/slot/Span.svelte +1 -2
  96. package/dist/ui/table/Table.svelte +28 -35
  97. package/dist/ui/table/TableBody.svelte +12 -18
  98. package/dist/ui/table/TableCell.svelte +10 -13
  99. package/dist/ui/table/TableFieldsEdition.svelte +51 -57
  100. package/dist/ui/table/TableHead.svelte +20 -19
  101. package/dist/ui/table/TableViewSelect.svelte +37 -50
  102. package/dist/ui/table/cell/TableCellArray.svelte +3 -5
  103. package/dist/ui/table/cell/TableCellBoolean.svelte +3 -4
  104. package/dist/ui/table/cell/TableCellNumber.svelte +1 -2
  105. package/dist/ui/table/cell/TableCellString.svelte +2 -5
  106. package/dist/ui/table/head/OrderButtons.svelte +37 -0
  107. package/dist/ui/table/head/OrderButtons.svelte.d.ts +20 -0
  108. package/dist/ui/table/head/TableHeadBoolean.svelte +3 -6
  109. package/dist/ui/table/head/TableHeadDate.svelte +110 -61
  110. package/dist/ui/table/head/TableHeadDefault.svelte +2 -5
  111. package/dist/ui/table/head/TableHeadNumber.svelte +76 -67
  112. package/dist/ui/table/head/TableHeadSelect.svelte +41 -47
  113. package/dist/ui/table/head/TableHeadString.svelte +8 -14
  114. package/dist/ui/tabs/Tabs.svelte +5 -8
  115. package/dist/ui/tabs/TabsIcon.svelte +28 -31
  116. package/dist/validation/zod.d.ts +12 -0
  117. package/dist/validation/zod.js +4 -2
  118. package/package.json +1 -1
@@ -1,53 +1,40 @@
1
- <script lang="ts">
2
- import { onMount } from 'svelte'
3
- import { mdiChevronDown, mdiContentSaveEditOutline, mdiPlus } from '@mdi/js'
4
- import { page } from '$app/stores'
5
- import { enhance } from '$app/forms'
6
-
7
- import { Icon } from '../icon/index.js'
8
- import { Dialog } from '../dialog/index.js'
9
- import { DropDown } from '../menu/index.js'
10
- import { InputText } from '../input/index.js'
11
- import { useForm } from '../../validation/form.js'
12
-
13
- type View = {
14
- id: string
15
- name: string
16
- query: string
17
- }
18
-
19
- export let key: string
20
- export let views: View[]
21
- export let action = ''
22
- export let actionCreate = '?/view_create'
23
- export let actionUpdate = '?/view_update'
24
- export let actionDelete = '?/view_delete'
25
-
26
- let dialog: HTMLDialogElement
27
- const form = useForm({
28
- onSuccess() {
29
- dialog.close()
30
- }
31
- })
32
-
33
- let query = getQuery($page.url)
34
- let selectedView = views.find((v) => v.query === query)
35
- let isNewView = !!query && !selectedView
36
-
37
- onMount(() =>
38
- page.subscribe(({ url }) => {
39
- query = getQuery(url)
40
- selectedView = views.find((v) => v.query === query)
41
- isNewView = !!query && !selectedView
42
- })
43
- )
44
-
45
- function getQuery({ searchParams }: URL) {
46
- const searchParam = new URLSearchParams(searchParams)
47
- searchParam.delete('skip')
48
- searchParam.delete('take')
49
- return searchParam.toString()
50
- }
1
+ <script>import { onMount } from "svelte";
2
+ import { mdiChevronDown, mdiContentSaveEditOutline, mdiPlus } from "@mdi/js";
3
+ import { page } from "$app/stores";
4
+ import { enhance } from "$app/forms";
5
+ import { Icon } from "../icon/index.js";
6
+ import { Dialog } from "../dialog/index.js";
7
+ import { DropDown } from "../menu/index.js";
8
+ import { InputText } from "../input/index.js";
9
+ import { useForm } from "../../validation/form.js";
10
+ export let key;
11
+ export let views;
12
+ export let action = "";
13
+ export let actionCreate = "?/view_create";
14
+ export let actionUpdate = "?/view_update";
15
+ export let actionDelete = "?/view_delete";
16
+ let dialog;
17
+ const form = useForm({
18
+ onSuccess() {
19
+ dialog.close();
20
+ }
21
+ });
22
+ let query = getQuery($page.url);
23
+ let selectedView = views.find((v) => v.query === query);
24
+ let isNewView = !!query && !selectedView;
25
+ onMount(
26
+ () => page.subscribe(({ url }) => {
27
+ query = getQuery(url);
28
+ selectedView = views.find((v) => v.query === query);
29
+ isNewView = !!query && !selectedView;
30
+ })
31
+ );
32
+ function getQuery({ searchParams }) {
33
+ const searchParam = new URLSearchParams(searchParams);
34
+ searchParam.delete("skip");
35
+ searchParam.delete("take");
36
+ return searchParam.toString();
37
+ }
51
38
  </script>
52
39
 
53
40
  <DropDown>
@@ -1,8 +1,6 @@
1
- <script lang="ts">
2
- import { Badge } from '../../badge/index.js'
3
- import { component, type ComponentAndProps } from '../../../utils/component.js'
4
-
5
- export let value: (ComponentAndProps | string | number | boolean)[]
1
+ <script>import { Badge } from "../../badge/index.js";
2
+ import { component } from "../../../utils/component.js";
3
+ export let value;
6
4
  </script>
7
5
 
8
6
  <td>
@@ -1,7 +1,6 @@
1
- <script lang="ts">
2
- import { mdiCheck, mdiClose } from '@mdi/js'
3
- import { Icon } from '../../icon/index.js'
4
- export let value: boolean
1
+ <script>import { mdiCheck, mdiClose } from "@mdi/js";
2
+ import { Icon } from "../../icon/index.js";
3
+ export let value;
5
4
  </script>
6
5
 
7
6
  <td>
@@ -1,5 +1,4 @@
1
- <script lang="ts">
2
- export let value: number
1
+ <script>export let value;
3
2
  </script>
4
3
 
5
4
  <td>
@@ -1,8 +1,5 @@
1
- <script lang="ts">
2
- import type { TableField } from '../index.js'
3
-
4
- export let value: string
5
- export let field: TableField
1
+ <script>export let value;
2
+ export let field;
6
3
  </script>
7
4
 
8
5
  <td data-field-key={field.key} data-field-type={field.type === 'textarea' ? 'textarea' : 'string'}>
@@ -0,0 +1,37 @@
1
+ <script>import { Icon } from "../../icon/index.js";
2
+ import { mdiSortAscending, mdiSortDescending } from "@mdi/js";
3
+ import { createEventDispatcher } from "svelte";
4
+ export let order;
5
+ export let iconAsc = mdiSortAscending;
6
+ export let iconDesc = mdiSortDescending;
7
+ const dispatch = createEventDispatcher();
8
+ const handleOrderClick = (orderBy) => () => {
9
+ if (order === orderBy)
10
+ order = void 0;
11
+ else
12
+ order = orderBy;
13
+ dispatch("change", order);
14
+ };
15
+ </script>
16
+
17
+ <div class="p-1 pt-2">
18
+ <span class="text-sm font-semibold opacity-70">Ordre:</span>
19
+ <div class="grid grid-cols-2 gap-2 pt-2">
20
+ <button
21
+ class="btn ring-primary"
22
+ class:ring-2={order === 'asc'}
23
+ on:click={handleOrderClick('asc')}
24
+ >
25
+ <Icon path={iconAsc} />
26
+ <span>Ascendant</span>
27
+ </button>
28
+ <button
29
+ class="btn ring-primary"
30
+ class:ring-2={order === 'desc'}
31
+ on:click={handleOrderClick('desc')}
32
+ >
33
+ <Icon path={iconDesc} />
34
+ <span>Descendant</span>
35
+ </button>
36
+ </div>
37
+ </div>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ order: "desc" | "asc" | undefined;
5
+ iconAsc?: string | undefined;
6
+ iconDesc?: string | undefined;
7
+ };
8
+ events: {
9
+ change: CustomEvent<"desc" | "asc" | undefined>;
10
+ } & {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export type OrderButtonsProps = typeof __propDef.props;
16
+ export type OrderButtonsEvents = typeof __propDef.events;
17
+ export type OrderButtonsSlots = typeof __propDef.slots;
18
+ export default class OrderButtons extends SvelteComponent<OrderButtonsProps, OrderButtonsEvents, OrderButtonsSlots> {
19
+ }
20
+ export {};
@@ -1,9 +1,6 @@
1
- <script lang="ts">
2
- import { mdiCheck, mdiClose } from '@mdi/js'
3
- import type { TableField } from '../index.js'
4
- import TableHeadSelect from './TableHeadSelect.svelte'
5
-
6
- export let field: TableField
1
+ <script>import { mdiCheck, mdiClose } from "@mdi/js";
2
+ import TableHeadSelect from "./TableHeadSelect.svelte";
3
+ export let field;
7
4
  </script>
8
5
 
9
6
  <TableHeadSelect
@@ -1,64 +1,77 @@
1
- <script lang="ts">
2
- import { goto } from '$app/navigation'
3
- import { page } from '$app/stores'
4
- import { mdiCalendarFilterOutline } from '@mdi/js'
5
-
6
- import { DropDown } from '../../menu/index.js'
7
- import { InputTime } from '../../input/index.js'
8
- import type { TableField } from '../index.js'
9
- import { formatRange } from '../../range/format.js'
10
- import { RangePicker } from '../../range/index.js'
11
- import { urlParam } from '../../../store/param.js'
12
- import { jsonParse } from '../../../utils/jsonParse.js'
13
- import { Icon } from '../../icon/index.js'
14
-
15
- export let field: Omit<TableField, 'getCell' | 'type'>
16
-
17
- let dropDown: DropDown
18
- let rangePicker: RangePicker
19
- const initialValue = jsonParse<{ start?: string; end?: string }>(
20
- $page.url.searchParams.get(field.key),
21
- {}
22
- )
23
-
24
- let range = {
25
- start: initialValue.start ? new Date(initialValue.start) : null,
26
- end: initialValue.end ? new Date(initialValue.end) : null
27
- }
28
-
29
- $: isValidPeriod = !!range.start && !!range.end
30
-
31
- function handleSubmit() {
32
- dropDown.hide()
33
- if (!isValidPeriod) return
34
- goto(
35
- $urlParam.with(
36
- {
37
- [field.key]: JSON.stringify({
38
- start: range.start?.toJSON(),
39
- end: range.end?.toJSON()
40
- })
41
- },
42
- 'skip',
43
- 'take'
44
- ),
45
- { replaceState: true, noScroll: true }
46
- )
47
- }
48
-
49
- function handleReset() {
50
- dropDown.hide()
51
- range = { start: null, end: null }
52
- rangePicker.clear()
53
- goto($urlParam.without(field.key, 'skip', 'take'), { replaceState: true, noScroll: true })
54
- }
1
+ <script>import { goto } from "$app/navigation";
2
+ import { page } from "$app/stores";
3
+ import {
4
+ mdiCalendarFilterOutline,
5
+ mdiSortClockAscendingOutline,
6
+ mdiSortClockDescendingOutline
7
+ } from "@mdi/js";
8
+ import { DropDown } from "../../menu/index.js";
9
+ import { InputTime } from "../../input/index.js";
10
+ import { formatRange } from "../../range/format.js";
11
+ import { RangePicker } from "../../range/index.js";
12
+ import { urlParam } from "../../../store/param.js";
13
+ import { jsonParse } from "../../../utils/jsonParse.js";
14
+ import { Icon } from "../../icon/index.js";
15
+ import OrderButtons from "./OrderButtons.svelte";
16
+ export let field;
17
+ let dropDown;
18
+ let rangePicker;
19
+ const initialValue = jsonParse(
20
+ $page.url.searchParams.get(field.key),
21
+ {}
22
+ );
23
+ let { order } = jsonParse($page.url.searchParams.get(field.key), {});
24
+ let range = {
25
+ start: initialValue.start ? new Date(initialValue.start) : null,
26
+ end: initialValue.end ? new Date(initialValue.end) : null
27
+ };
28
+ let isValidPeriod = !!range.start && !!range.end;
29
+ function updateUrl() {
30
+ isValidPeriod = !!range.start && !!range.end;
31
+ if (!isValidPeriod && !order) {
32
+ goto($urlParam.without(field.key, "skip", "take"), {
33
+ replaceState: true,
34
+ noScroll: true,
35
+ keepFocus: true
36
+ });
37
+ return;
38
+ }
39
+ goto(
40
+ $urlParam.with(
41
+ {
42
+ [field.key]: JSON.stringify({
43
+ ...isValidPeriod ? {
44
+ start: range.start?.toJSON(),
45
+ end: range.end?.toJSON()
46
+ } : {},
47
+ ...order ? { order } : {}
48
+ })
49
+ },
50
+ "skip",
51
+ "take"
52
+ ),
53
+ { replaceState: true, noScroll: true, keepFocus: true }
54
+ );
55
+ }
56
+ function handleReset() {
57
+ isValidPeriod = false;
58
+ range.start = null;
59
+ range = { start: null, end: null };
60
+ dropDown.hide();
61
+ rangePicker.clear();
62
+ goto($urlParam.without(field.key, "skip", "take"), {
63
+ replaceState: true,
64
+ noScroll: true,
65
+ keepFocus: true
66
+ });
67
+ }
55
68
  </script>
56
69
 
57
70
  <th class="p-1">
58
71
  <DropDown
59
72
  bind:this={dropDown}
60
- on:mouseLeave={handleSubmit}
61
73
  tippyProps={{ appendTo: () => document.body }}
74
+ hideOnNav={false}
62
75
  class="max-h-none"
63
76
  >
64
77
  <button slot="activator" class="menu-item min-h-8 w-full flex-wrap gap-y-1">
@@ -74,25 +87,61 @@
74
87
  {formatRange(range)}
75
88
  </span>
76
89
  {/if}
90
+ {#if order}
91
+ <Icon
92
+ path={order === 'asc' ? mdiSortClockAscendingOutline : mdiSortClockDescendingOutline}
93
+ size={18}
94
+ class="fill-primary"
95
+ />
96
+ {/if}
77
97
  </button>
78
98
 
99
+ <OrderButtons
100
+ bind:order
101
+ on:change={() => {
102
+ updateUrl()
103
+ dropDown.hide()
104
+ }}
105
+ iconAsc={mdiSortClockAscendingOutline}
106
+ iconDesc={mdiSortClockDescendingOutline}
107
+ />
108
+
79
109
  <form
80
- class="flex flex-col font-normal"
81
- on:submit|preventDefault={handleSubmit}
110
+ class="mt-6 flex flex-col font-normal"
111
+ on:submit|preventDefault={() => dropDown.hide()}
82
112
  data-sveltekit-replacestate
83
113
  >
84
- <RangePicker bind:this={rangePicker} numberOfMonths={1} bind:range />
114
+ <RangePicker
115
+ bind:this={rangePicker}
116
+ numberOfMonths={1}
117
+ on:change={({ detail: newRange }) => {
118
+ range = newRange
119
+ updateUrl()
120
+ }}
121
+ />
85
122
 
86
123
  <input class="hidden" type="text" name="start" value={range.start?.toJSON()} />
87
124
  <input class="hidden" type="text" name="end" value={range.end?.toJSON()} />
88
125
 
89
126
  <div class="m-2 flex gap-2">
90
- <InputTime label="A partir de" bind:value={range.start} enhanceDisabled class="grow" />
91
- <InputTime label="Jusqu'à" bind:value={range.end} enhanceDisabled class="grow" />
127
+ <InputTime
128
+ label="A partir de"
129
+ bind:value={range.start}
130
+ enhanceDisabled
131
+ class="grow"
132
+ on:input={updateUrl}
133
+ />
134
+ <InputTime
135
+ label="Jusqu'à"
136
+ bind:value={range.end}
137
+ enhanceDisabled
138
+ class="grow"
139
+ on:input={updateUrl}
140
+ />
92
141
  </div>
93
142
 
94
143
  <div class="m-2 flex flex-row-reverse gap-2">
95
- <button class="btn"> Valider </button>
144
+ <button class="btn">Ok</button>
96
145
  <button class="btn btn-ghost" type="button" on:click={handleReset}>Effacer</button>
97
146
  </div>
98
147
  </form>
@@ -1,8 +1,5 @@
1
- <script lang="ts">
2
- import type { TableField } from '../index.js'
3
- import { tip } from '../../../action/tip.js'
4
-
5
- export let field: TableField
1
+ <script>import { tip } from "../../../action/tip.js";
2
+ export let field;
6
3
  </script>
7
4
 
8
5
  <th use:tip={{ disable: !field.hint, content: field.hint }}>
@@ -1,68 +1,59 @@
1
- <script lang="ts">
2
- import { onMount } from 'svelte'
3
- import type { TippyInstance } from '../../../utils/tippy.js'
4
- import debounce from 'debounce'
5
- import { goto } from '$app/navigation'
6
- import { page } from '$app/stores'
7
-
8
- import { DropDown } from '../../menu/index.js'
9
- import { InputNumber } from '../../input/index.js'
10
- import { urlParam } from '../../../store/param.js'
11
- import { jsonParse } from '../../../utils/jsonParse.js'
12
- import type { TableField } from '../field.js'
13
- import { mdiFilterMultipleOutline } from '@mdi/js'
14
- import { Icon } from '../../icon/index.js'
15
-
16
- export let field: TableField
17
-
18
- let tip: TippyInstance
19
- type Range = { min: number | undefined; max: number | undefined }
20
-
21
- let { min, max } = initRange($page.url)
22
- onMount(() => page.subscribe(({ url }) => ({ min, max } = initRange(url))))
23
-
24
- function initRange({ searchParams }: URL) {
25
- return jsonParse<Range>(searchParams.get(field.key), {
26
- min: undefined,
27
- max: undefined
28
- })
29
- }
30
-
31
- const udpateUrl = debounce(() => {
32
- if (isDefined(min) || isDefined(max)) {
33
- goto(
34
- $urlParam.with(
35
- {
36
- [field.key]: JSON.stringify({
37
- ...(isDefined(min) ? { min } : {}),
38
- ...(isDefined(max) ? { max } : {})
39
- })
40
- },
41
- 'skip',
42
- 'take'
43
- ),
44
- {
45
- noScroll: true,
46
- keepFocus: true
47
- }
48
- )
49
- return
50
- }
51
- goto($urlParam.without(field.key, 'skip', 'take'), { noScroll: true, keepFocus: true })
52
- }, 250)
53
-
54
- function handleReset() {
55
- min = undefined
56
- max = undefined
57
- tip.hide()
58
- goto($urlParam.without(field.key, 'skip', 'take'), { noScroll: true, keepFocus: true })
59
- }
60
-
61
- function isDefined(v: number | undefined | null): v is number {
62
- return typeof v === 'number'
63
- }
64
-
65
- $: isNegatifRange = isDefined(min) && isDefined(max) && max < min
1
+ <script>import { onMount } from "svelte";
2
+ import debounce from "debounce";
3
+ import { goto } from "$app/navigation";
4
+ import { page } from "$app/stores";
5
+ import { DropDown } from "../../menu/index.js";
6
+ import { InputNumber } from "../../input/index.js";
7
+ import { urlParam } from "../../../store/param.js";
8
+ import { jsonParse } from "../../../utils/jsonParse.js";
9
+ import { mdiFilterMultipleOutline, mdiSortAscending, mdiSortDescending } from "@mdi/js";
10
+ import { Icon } from "../../icon/index.js";
11
+ import OrderButtons from "./OrderButtons.svelte";
12
+ export let field;
13
+ let tip;
14
+ let { min, max, order } = initRange($page.url);
15
+ onMount(() => page.subscribe(({ url }) => ({ min, max, order } = initRange(url))));
16
+ function initRange({ searchParams }) {
17
+ return jsonParse(searchParams.get(field.key), {
18
+ min: void 0,
19
+ max: void 0,
20
+ order: void 0
21
+ });
22
+ }
23
+ const updateUrl = debounce(() => {
24
+ if (isDefined(min) || isDefined(max) || order) {
25
+ goto(
26
+ $urlParam.with(
27
+ {
28
+ [field.key]: JSON.stringify({
29
+ ...isDefined(min) ? { min } : {},
30
+ ...isDefined(max) ? { max } : {},
31
+ ...order ? { order } : {}
32
+ })
33
+ },
34
+ "skip",
35
+ "take"
36
+ ),
37
+ {
38
+ noScroll: true,
39
+ keepFocus: true
40
+ }
41
+ );
42
+ return;
43
+ }
44
+ goto($urlParam.without(field.key, "skip", "take"), { noScroll: true, keepFocus: true });
45
+ }, 250);
46
+ function handleReset() {
47
+ min = void 0;
48
+ max = void 0;
49
+ tip.hide();
50
+ goto($urlParam.without(field.key, "skip", "take"), { noScroll: true, keepFocus: true });
51
+ }
52
+ function isDefined(v) {
53
+ return typeof v === "number";
54
+ }
55
+ $:
56
+ isNegatifRange = isDefined(min) && isDefined(max) && max < min;
66
57
  </script>
67
58
 
68
59
  <th class="p-1">
@@ -92,13 +83,31 @@
92
83
  {/if}
93
84
  </span>
94
85
  {/if}
86
+ {#if order}
87
+ <Icon
88
+ path={order === 'asc' ? mdiSortAscending : mdiSortDescending}
89
+ size={18}
90
+ class="fill-primary"
91
+ />
92
+ {/if}
95
93
  </button>
96
94
 
95
+ <OrderButtons
96
+ bind:order
97
+ on:change={() => {
98
+ updateUrl()
99
+ tip.hide()
100
+ }}
101
+ />
102
+
103
+ <div class="divider"></div>
104
+
105
+ <span class="p-1 py-1 text-sm font-semibold opacity-70">Filtre:</span>
97
106
  <form class="grid grid-cols-2 gap-2 p-1" on:submit|preventDefault={() => tip.hide()}>
98
- <InputNumber bind:value={min} on:input={udpateUrl} input={{ placeholder: 'Min' }} />
107
+ <InputNumber bind:value={min} on:input={updateUrl} input={{ placeholder: 'Min' }} />
99
108
  <InputNumber
100
109
  bind:value={max}
101
- on:input={udpateUrl}
110
+ on:input={updateUrl}
102
111
  hint={isNegatifRange ? 'Doit être plus grand' : ''}
103
112
  input={{ placeholder: 'Max' }}
104
113
  />