sveltekit-ui 1.0.16 → 1.0.18

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.
@@ -609,7 +609,7 @@ export function create_content_manager(config) {
609
609
  const static_val = set_closurable(val_loc?.attributes?.val)
610
610
  if (Array.isArray(static_val)) {
611
611
  for (let i = 0; i < static_val.length; i++) {
612
- console.log("loop_test", val_loc?.attributes)
612
+ // console.log("loop_test", val_loc?.attributes)
613
613
  let children = []
614
614
  if (Array.isArray(val_loc?.children) && val_loc?.children.length > 0) {
615
615
  is_children = true
@@ -13,38 +13,26 @@
13
13
  <thead>
14
14
  <tr>
15
15
  <th>Sort Order</th>
16
- <th>Data from Row Path</th>
16
+ <th>Data Variable Path</th>
17
17
  <th>Is Ascending</th>
18
+ <th>Remove</th>
18
19
  <th></th>
19
20
  </tr>
20
21
  </thead>
21
22
  <tbody>
22
- {#if Array.isArray(manager?.sorts_prepped) && manager?.sorts_prepped.length > 0}
23
- {#each manager?.sorts_prepped as sort_prepped, i}
24
- <tr>
25
- <td>{i == 0 ? "Primary" : "Subsort"}</td>
26
- <td>
27
- <VariablePathInput manager={sort_prepped?.data_row_variable_path_input_manager} />
28
- </td>
29
- <td>
30
- <Checkbox manager={sort_prepped?.is_ascending_checkbox_manager} />
31
- </td>
32
- <td>
33
- <Button manager={sort_prepped?.extra_button_manager} />
34
- <Popover manager={sort_prepped?.extra_popover_manager}>
35
- {#snippet content()}
36
- {#if Array(manager?.sorts_prepped) && manager?.sorts_prepped.length > 0 && i > 1}
37
- <Button manager={sort_prepped?.shift_up_button_manager} />
38
- {/if}
39
- {#if Array(manager?.sorts_prepped) && manager?.sorts_prepped.length > 1 && i < manager?.sorts_prepped.length}
40
- <Button manager={sort_prepped?.shift_down_button_manager} />
41
- {/if}
42
- <Button manager={sort_prepped?.delete_button_manager} />
43
- {/snippet}
44
- </Popover>
45
- </td>
46
- </tr>
47
- {/each}
23
+ {#if Array.isArray(manager?.sorts_prepped) && manager?.sorts_prepped.length > 0}
24
+ {#each manager?.sorts_prepped as sort_prepped, i}
25
+ <tr>
26
+ <td>{i == 0 ? "Primary" : "Subsort"}</td>
27
+ <td>
28
+ <VariablePathInput manager={sort_prepped?.variable_path_input_manager} />
29
+ </td>
30
+ <td>
31
+ <Checkbox manager={sort_prepped?.is_ascending_checkbox_manager} />
32
+ </td>
33
+ <td><Button manager={sort_prepped?.delete_button_manager} /></td>
34
+ </tr>
35
+ {/each}
48
36
  {:else}
49
37
  <tr>
50
38
  <td colspan="4">No Sorts added yet</td>
@@ -53,7 +41,9 @@
53
41
  </tbody>
54
42
  </table>
55
43
  </div>
56
- <Button manager={manager?.add_sort_button_manager} />
44
+ <div style="margin-top: 1rem;">
45
+ <Button manager={manager?.add_sort_button_manager} />
46
+ </div>
57
47
  {/snippet}
58
48
 
59
49
  {#if manager?.is_popover}
@@ -65,7 +55,10 @@
65
55
  {@render sort_content()}
66
56
  {/snippet}
67
57
  {#snippet footer()}
68
- <Button manager={manager?.apply_sorting_button_manager} />
58
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
59
+ <Button manager={manager?.save_server_sort_button_manager} />
60
+ <Button manager={manager?.apply_sorting_button_manager} />
61
+ </div>
69
62
  {/snippet}
70
63
  </Popover>
71
64
  {:else}
@@ -73,7 +66,7 @@
73
66
  {/if}
74
67
 
75
68
  <style>
76
- th{
69
+ th {
77
70
  font-size: 1.2rem;
78
71
  }
79
- </style>
72
+ </style>
@@ -12,6 +12,7 @@ export function create_sort_by_input_manager(config) {
12
12
  let popover_toggle_button_manager = $state(null)
13
13
  let popover_manager = $state(null)
14
14
  let apply_sorting_button_manager = $state(null)
15
+ let save_server_sort_button_manager = $state(null)
15
16
  let add_sort_button_manager = $state(null)
16
17
  let sorts_prepped = $state(null)
17
18
 
@@ -23,7 +24,7 @@ export function create_sort_by_input_manager(config) {
23
24
  for (let sort_prepped of sorts_prepped) {
24
25
  sorts.push({
25
26
  is_ascending: sort_prepped?.is_ascending_checkbox_manager?.val,
26
- data_row_variable_path: sort_prepped?.data_row_variable_path_input_manager?.val,
27
+ variable_path: sort_prepped?.variable_path_input_manager?.val,
27
28
  })
28
29
  }
29
30
  }
@@ -34,54 +35,17 @@ export function create_sort_by_input_manager(config) {
34
35
  let sorts_prepped_loc = []
35
36
  if (Array.isArray(sorts)) {
36
37
  for (let i = 0; i < sorts.length; i++) {
37
- let extra_button_manager = $state(null)
38
- let extra_popover_manager = $state(null)
39
- extra_popover_manager = create_popover_manager({
40
- target_width: 200,
41
- target_height: 200,
42
- type: "dropdown",
43
- anchor_id: () => `button_${extra_button_manager?.id}`,
44
- })
45
- extra_button_manager = create_button_manager({
46
- type: "soft",
47
- support_icon: "three_dots",
48
- icon_sw: 60,
49
- is_uniform: true,
50
- popover_target: () => `popover_${extra_popover_manager?.id}`,
51
- })
52
38
  let delete_button_manager = create_button_manager({
53
- type: "soft",
54
- text: "Delete",
39
+ type: "outlined",
40
+ is_uniform: true,
55
41
  support_icon: "x",
56
42
  color: "var(--error-t)",
57
- text_align: "left",
58
43
  on_click: () => {
59
- extra_popover_manager.close()
60
44
  if (Array.isArray(sorts_prepped) && i >= 0 && i < sorts_prepped.length) {
61
45
  sorts_prepped.splice(i, 1)
62
46
  }
63
47
  },
64
48
  })
65
- let shift_up_button_manager = create_button_manager({
66
- type: "soft",
67
- text: "Shift Up",
68
- support_icon: "arrow_tailed",
69
- icon_deg: 270,
70
- text_align: "left",
71
- on_click: () => {
72
- console.log("shift sort up")
73
- },
74
- })
75
- let shift_down_button_manager = create_button_manager({
76
- type: "soft",
77
- text: "Shift Down",
78
- support_icon: "arrow_tailed",
79
- text_align: "left",
80
- icon_deg: 90,
81
- on_click: () => {
82
- console.log("shift sort down")
83
- },
84
- })
85
49
  let is_ascending_checkbox_manager = create_checkbox_manager({
86
50
  type: "toggle",
87
51
  val: sorts?.[i]?.is_ascending ?? null,
@@ -89,27 +53,25 @@ export function create_sort_by_input_manager(config) {
89
53
  console.log("toggle is ascending")
90
54
  },
91
55
  })
92
- let data_row_variable_path_input_manager = create_variable_path_input_manager({
56
+ let variable_path_input_manager = create_variable_path_input_manager({
93
57
  is_popover: false,
94
58
  defined_data_type: row_data_type,
95
59
  get_defined_options: config?.get_defined_options,
96
- val: sorts?.[i]?.data_row_variable_path ?? null,
60
+ val: sorts?.[i]?.variable_path ?? null,
61
+ on_finish: () => variable_path_input_manager.close_popover(),
97
62
  })
98
63
  sorts_prepped_loc.push({
99
64
  ...sorts?.[i],
100
- extra_button_manager: extra_button_manager,
101
- extra_popover_manager: extra_popover_manager,
102
65
  delete_button_manager: delete_button_manager,
103
- shift_up_button_manager: shift_up_button_manager,
104
- shift_down_button_manager: shift_down_button_manager,
105
66
  is_ascending_checkbox_manager: is_ascending_checkbox_manager,
106
- data_row_variable_path_input_manager: data_row_variable_path_input_manager,
67
+ variable_path_input_manager: variable_path_input_manager,
107
68
  })
108
69
  }
109
70
  }
110
71
  sorts_prepped = sorts_prepped_loc
111
72
  }
112
73
 
74
+ let save_server_sort_is_loading = $state(false)
113
75
  function init(config) {
114
76
  popover_manager = create_popover_manager({
115
77
  header: "Sort By",
@@ -124,9 +86,27 @@ export function create_sort_by_input_manager(config) {
124
86
  popover_target: () => `popover_${popover_manager?.id}`,
125
87
  })
126
88
  apply_sorting_button_manager = create_button_manager({
127
- text: "Apply Sorting",
89
+ text: "Apply Local Sort",
128
90
  on_click: () => {
129
- console.log("Apply Sorting")
91
+ if (typeof config?.apply_sort == "function") {
92
+ config?.apply_sort(val)
93
+ }
94
+ },
95
+ })
96
+ save_server_sort_button_manager = create_button_manager({
97
+ type: "outlined",
98
+ text: "Save Server Sort",
99
+ on_click: async () => {
100
+ save_server_sort_is_loading = true
101
+ if (typeof config?.save_server_sort == "function") {
102
+ const res = await config?.save_server_sort(val)
103
+ if (res?.is_success) {
104
+ save_server_sort_button_manager.success_trigger()
105
+ } else {
106
+ save_server_sort_button_manager.error_trigger()
107
+ }
108
+ }
109
+ save_server_sort_is_loading = false
130
110
  },
131
111
  })
132
112
  add_sort_button_manager = create_button_manager({
@@ -139,7 +119,7 @@ export function create_sort_by_input_manager(config) {
139
119
  for (let sort_prepped of sorts_prepped) {
140
120
  sorts.push({
141
121
  is_ascending: sort_prepped?.is_ascending_checkbox_manager?.val,
142
- data_row_variable_path: sort_prepped?.data_row_variable_path_input_manager?.val,
122
+ variable_path: sort_prepped?.variable_path_input_manager?.val,
143
123
  })
144
124
  }
145
125
  }
@@ -147,7 +127,7 @@ export function create_sort_by_input_manager(config) {
147
127
  ...sorts,
148
128
  {
149
129
  is_ascending: false,
150
- data_row_variable_path: null,
130
+ variable_path: null,
151
131
  },
152
132
  ]
153
133
  set_sorts_prepped(sorts)
@@ -180,6 +160,9 @@ export function create_sort_by_input_manager(config) {
180
160
  get apply_sorting_button_manager() {
181
161
  return apply_sorting_button_manager
182
162
  },
163
+ get save_server_sort_button_manager() {
164
+ return save_server_sort_button_manager
165
+ },
183
166
  get sorts_prepped() {
184
167
  return sorts_prepped
185
168
  },
@@ -15,14 +15,11 @@ import {
15
15
  csv_to_json,
16
16
  create_unique_id,
17
17
  set_definition_stack,
18
- set_def,
19
18
  get_def_from_variable_path,
20
19
  variables_data_type_remaining_to_astc,
21
20
  } from "../../client/index.js"
22
21
  import { tick } from "svelte"
23
22
  import { browser } from "$app/environment"
24
- // tbd quick sort for column override default sort or work conjuction with
25
- // select bulk rows with condition (eg ["row","points"] greater_than 2000) where
26
23
 
27
24
  export function create_table_advanced_manager(config) {
28
25
  const id = create_unique_id(null, 20)
@@ -62,6 +59,7 @@ export function create_table_advanced_manager(config) {
62
59
  let rows_per_page_dropdown_manager = $state(null)
63
60
  let cur_page = $state(1)
64
61
  let load_more_button_manager = $state(null)
62
+ let sort_by = $state(null)
65
63
  let sort_by_input_manager = $state(null)
66
64
  let is_bulk_select = $state(false)
67
65
  let toggle_bulk_selectable_button_manager = $state(null)
@@ -134,21 +132,45 @@ export function create_table_advanced_manager(config) {
134
132
  table_search_text_input_manager?.val.trim() !== ""
135
133
  ) {
136
134
  for (let i = 0; i < rows_prepped.length; i++) {
137
- if (rows_prepped[i]?.searchable_text.includes(table_search_text_input_manager?.val.toLowerCase())) {
135
+ if (
136
+ rows_prepped[i]?.searchable_text &&
137
+ rows_prepped[i]?.searchable_text.toLowerCase().includes(table_search_text_input_manager.val.toLowerCase())
138
+ ) {
138
139
  row_indexes.push(i)
139
140
  }
140
141
  }
141
142
  } else {
142
143
  row_indexes = Array.isArray(rows_prepped) ? Array.from({ length: rows_prepped.length }, (_, i) => i) : []
143
144
  }
144
- // tbd sort and sub sorts correctly
145
- // if (Array.isArray(sort_by_input_manager?.val)) {
146
- // for (let sort_by_item of sort_by_input_manager?.val) {
147
- // // sort_by_item?.is_ascending
148
- // // sort_by_item?.data_row_variable_path
149
- // // const val_at_path = get_def_from_variable_path(sort_by_item?.data_row_variable_path)
150
- // }
151
- // }
145
+ function get_column_value(row, column_id) {
146
+ const attrs = row?.columns?.[column_id]?.body_content?.attributes ?? {}
147
+ const val_from_variable_path = attrs.val_from_variable_path ?? attrs.content_from_variable_path
148
+ if (val_from_variable_path) {
149
+ return get_def_from_variable_path(val_from_variable_path, [{ row_i: row?.row_i }, ...definition_stack])
150
+ }
151
+ return attrs.val ?? attrs.content ?? null
152
+ }
153
+ if (Array.isArray(sort_by) && sort_by.length > 0) {
154
+ row_indexes.sort((a, b) => {
155
+ for (let sort_item of sort_by) {
156
+ const column_id = sort_item?.variable_path?.[0]
157
+ const is_ascending = !!sort_item?.is_ascending
158
+ let a_val = get_column_value(rows_prepped[a], column_id)
159
+ let b_val = get_column_value(rows_prepped[b], column_id)
160
+ if (a_val === b_val) continue
161
+ if (a_val == null) return is_ascending ? 1 : -1
162
+ if (b_val == null) return is_ascending ? -1 : 1
163
+ if (typeof a_val === "number" && typeof b_val === "number") {
164
+ return is_ascending ? a_val - b_val : b_val - a_val
165
+ }
166
+ const a_str = Array.isArray(a_val) ? a_val.join(",") : String(a_val)
167
+ const b_str = Array.isArray(b_val) ? b_val.join(",") : String(b_val)
168
+ if (a_str === b_str) continue
169
+ return is_ascending ? a_str.localeCompare(b_str) : b_str.localeCompare(a_str)
170
+ }
171
+ return 0
172
+ })
173
+ }
152
174
  return row_indexes
153
175
  }
154
176
 
@@ -166,7 +188,6 @@ export function create_table_advanced_manager(config) {
166
188
  const raf = () => (browser ? new Promise(requestAnimationFrame) : new Promise((r) => setTimeout(r, 0)))
167
189
 
168
190
  async function set_rows_prepped(columns_prepped_input) {
169
- console.log("set_rows_prepped", rows_data)
170
191
  is_loading_rows = true
171
192
  rows_prepped = []
172
193
  loading_rows_progress = 0
@@ -191,7 +212,6 @@ export function create_table_advanced_manager(config) {
191
212
  }
192
213
 
193
214
  function get_row_prepped(columns_prepped_input, row_data, row_i) {
194
- console.log("get_row_prepped", { row_data, row_i, ds: [{ [row_iter_identifier]: row_i }, ...definition_stack] })
195
215
  let searchable_text = ""
196
216
  let columns_prepped_loc = {}
197
217
  if (Array.isArray(column_ids_display_order)) {
@@ -458,7 +478,6 @@ export function create_table_advanced_manager(config) {
458
478
  }
459
479
  )
460
480
  } else {
461
- console.log("insert_column_error_tbd", res)
462
481
  preempt_insert_column_popover_manager.show_temp_message("Error inserting column", "error", 1800, false)
463
482
  }
464
483
  }
@@ -473,7 +492,6 @@ export function create_table_advanced_manager(config) {
473
492
  const path_to_set = [...rows_data_from_variable_path, Number.isInteger(row_i) ? row_i : 0]
474
493
  let editable_row = null
475
494
  if (!Number.isInteger(row_i)) {
476
- console.log("columns_prepped", columns_prepped)
477
495
  editable_row = {}
478
496
  } else {
479
497
  editable_row = get_def_from_variable_path([...rows_data_from_variable_path, row_i], definition_stack)
@@ -508,7 +526,6 @@ export function create_table_advanced_manager(config) {
508
526
  on_click: async () => {
509
527
  upsert_row_is_loading = true
510
528
  const row_data = get_def_from_variable_path([row_edit_def_identifier], row_definition_stack)
511
- console.log("edited_row", { row_i, row_data })
512
529
  if (Number.isInteger(row_i)) {
513
530
  if (typeof config?.on_event == "function") {
514
531
  const res = await config?.on_event({
@@ -544,7 +561,6 @@ export function create_table_advanced_manager(config) {
544
561
  row: row_data,
545
562
  path: path_to_set,
546
563
  })
547
- console.log("insert_row_res", { res, columns_prepped })
548
564
  if (res?.is_success) {
549
565
  preempt_insert_row_popover_manager.show_temp_message(
550
566
  "Successfully inserted row",
@@ -554,7 +570,6 @@ export function create_table_advanced_manager(config) {
554
570
  () => set_rows_prepped(columns_prepped)
555
571
  )
556
572
  } else {
557
- console.log("insert_row_error_tbd", res)
558
573
  preempt_insert_row_popover_manager.show_temp_message("Error insering row", "error", 1800, false)
559
574
  }
560
575
  }
@@ -720,7 +735,6 @@ export function create_table_advanced_manager(config) {
720
735
  }
721
736
 
722
737
  function reset_definition_stack(input) {
723
- console.log("reset_definition_stack", deep_copy(input))
724
738
  definition_stack = input
725
739
  set_rows_prepped(columns_prepped)
726
740
  }
@@ -734,6 +748,7 @@ export function create_table_advanced_manager(config) {
734
748
  table_id = config?.table_id
735
749
  table_name = config?.table_name
736
750
  table_description = config?.table_description
751
+ sort_by = config?.table?.sort_by
737
752
  rows_data_from_variable_path = config?.rows_data_from_variable_path
738
753
  row_iter_identifier = config?.row_iter_identifier ?? "row_i"
739
754
  definition_stack = config?.definition_stack
@@ -785,8 +800,23 @@ export function create_table_advanced_manager(config) {
785
800
  })
786
801
  sort_by_input_manager = create_sort_by_input_manager({
787
802
  is_popover: true,
788
- val: config?.val?.sort_by,
789
- // row_data_type: row_data_type,
803
+ val: sort_by,
804
+ apply_sort: (input) => {
805
+ sort_by = input
806
+ },
807
+ save_server_sort: async (input) => {
808
+ if (typeof config?.on_event == "function") {
809
+ const res = await config?.on_event({
810
+ type: "update_table_server_sort",
811
+ input: input,
812
+ })
813
+ return res
814
+ }
815
+ },
816
+ get_defined_options: () => {
817
+ const defined_options = Object.keys(columns_prepped || {}).map((h) => ({ key: h, name: h }))
818
+ return defined_options
819
+ },
790
820
  })
791
821
  toggle_bulk_selectable_button_manager = create_button_manager({
792
822
  type: "soft",
@@ -977,7 +1007,6 @@ export function create_table_advanced_manager(config) {
977
1007
  }
978
1008
  )
979
1009
  } else {
980
- console.log("update_row_error_tbd", res)
981
1010
  prempt_bulk_upload_rows_popover_manager.show_temp_message("Error bulk inserting rows", "error", 1800, false)
982
1011
  }
983
1012
  }
@@ -2,7 +2,6 @@ import { create_popover_manager } from "../Popover/index.svelte.js"
2
2
  import { create_button_manager } from "../Button/index.svelte.js"
3
3
  import { create_text_input_manager } from "../TextInput/index.svelte.js"
4
4
  import { create_dropdown_manager } from "../Dropdown/index.svelte.js"
5
- import { deep_copy } from "../../client/index.js"
6
5
 
7
6
  export function create_variable_path_input_manager(config) {
8
7
  let popover_manager = $state(null)
@@ -23,7 +22,6 @@ export function create_variable_path_input_manager(config) {
23
22
  }
24
23
 
25
24
  function prep_path(input) {
26
- console.log("prep_path", input)
27
25
  let path_prepped_loc = $state([])
28
26
  if (Array.isArray(input)) {
29
27
  let variable_data_type_at_path = Array.isArray(defined_options)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sveltekit-ui",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "A SvelteKit UI component library for building modern web applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,13 +25,13 @@
25
25
  "@sveltejs/kit": "^2.22.2"
26
26
  },
27
27
  "devDependencies": {
28
- "@sveltejs/adapter-vercel": "^5.8.1",
29
- "@sveltejs/kit": "^2.27.2",
30
- "@sveltejs/package": "^2.4.0",
28
+ "@sveltejs/adapter-vercel": "^5.8.2",
29
+ "@sveltejs/kit": "^2.27.3",
30
+ "@sveltejs/package": "^2.4.1",
31
31
  "@sveltejs/vite-plugin-svelte": "^6.1.0",
32
32
  "@vercel/analytics": "^1.5.0",
33
33
  "typescript": "^5.9.2",
34
- "vite": "^7.1.0"
34
+ "vite": "^7.1.1"
35
35
  },
36
36
  "homepage": "https://www.sveltekit-ui.com",
37
37
  "keywords": [
@@ -609,7 +609,7 @@ export function create_content_manager(config) {
609
609
  const static_val = set_closurable(val_loc?.attributes?.val)
610
610
  if (Array.isArray(static_val)) {
611
611
  for (let i = 0; i < static_val.length; i++) {
612
- console.log("loop_test", val_loc?.attributes)
612
+ // console.log("loop_test", val_loc?.attributes)
613
613
  let children = []
614
614
  if (Array.isArray(val_loc?.children) && val_loc?.children.length > 0) {
615
615
  is_children = true
@@ -13,38 +13,26 @@
13
13
  <thead>
14
14
  <tr>
15
15
  <th>Sort Order</th>
16
- <th>Data from Row Path</th>
16
+ <th>Data Variable Path</th>
17
17
  <th>Is Ascending</th>
18
+ <th>Remove</th>
18
19
  <th></th>
19
20
  </tr>
20
21
  </thead>
21
22
  <tbody>
22
- {#if Array.isArray(manager?.sorts_prepped) && manager?.sorts_prepped.length > 0}
23
- {#each manager?.sorts_prepped as sort_prepped, i}
24
- <tr>
25
- <td>{i == 0 ? "Primary" : "Subsort"}</td>
26
- <td>
27
- <VariablePathInput manager={sort_prepped?.data_row_variable_path_input_manager} />
28
- </td>
29
- <td>
30
- <Checkbox manager={sort_prepped?.is_ascending_checkbox_manager} />
31
- </td>
32
- <td>
33
- <Button manager={sort_prepped?.extra_button_manager} />
34
- <Popover manager={sort_prepped?.extra_popover_manager}>
35
- {#snippet content()}
36
- {#if Array(manager?.sorts_prepped) && manager?.sorts_prepped.length > 0 && i > 1}
37
- <Button manager={sort_prepped?.shift_up_button_manager} />
38
- {/if}
39
- {#if Array(manager?.sorts_prepped) && manager?.sorts_prepped.length > 1 && i < manager?.sorts_prepped.length}
40
- <Button manager={sort_prepped?.shift_down_button_manager} />
41
- {/if}
42
- <Button manager={sort_prepped?.delete_button_manager} />
43
- {/snippet}
44
- </Popover>
45
- </td>
46
- </tr>
47
- {/each}
23
+ {#if Array.isArray(manager?.sorts_prepped) && manager?.sorts_prepped.length > 0}
24
+ {#each manager?.sorts_prepped as sort_prepped, i}
25
+ <tr>
26
+ <td>{i == 0 ? "Primary" : "Subsort"}</td>
27
+ <td>
28
+ <VariablePathInput manager={sort_prepped?.variable_path_input_manager} />
29
+ </td>
30
+ <td>
31
+ <Checkbox manager={sort_prepped?.is_ascending_checkbox_manager} />
32
+ </td>
33
+ <td><Button manager={sort_prepped?.delete_button_manager} /></td>
34
+ </tr>
35
+ {/each}
48
36
  {:else}
49
37
  <tr>
50
38
  <td colspan="4">No Sorts added yet</td>
@@ -53,7 +41,9 @@
53
41
  </tbody>
54
42
  </table>
55
43
  </div>
56
- <Button manager={manager?.add_sort_button_manager} />
44
+ <div style="margin-top: 1rem;">
45
+ <Button manager={manager?.add_sort_button_manager} />
46
+ </div>
57
47
  {/snippet}
58
48
 
59
49
  {#if manager?.is_popover}
@@ -65,7 +55,10 @@
65
55
  {@render sort_content()}
66
56
  {/snippet}
67
57
  {#snippet footer()}
68
- <Button manager={manager?.apply_sorting_button_manager} />
58
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
59
+ <Button manager={manager?.save_server_sort_button_manager} />
60
+ <Button manager={manager?.apply_sorting_button_manager} />
61
+ </div>
69
62
  {/snippet}
70
63
  </Popover>
71
64
  {:else}
@@ -73,7 +66,7 @@
73
66
  {/if}
74
67
 
75
68
  <style>
76
- th{
69
+ th {
77
70
  font-size: 1.2rem;
78
71
  }
79
- </style>
72
+ </style>
@@ -12,6 +12,7 @@ export function create_sort_by_input_manager(config) {
12
12
  let popover_toggle_button_manager = $state(null)
13
13
  let popover_manager = $state(null)
14
14
  let apply_sorting_button_manager = $state(null)
15
+ let save_server_sort_button_manager = $state(null)
15
16
  let add_sort_button_manager = $state(null)
16
17
  let sorts_prepped = $state(null)
17
18
 
@@ -23,7 +24,7 @@ export function create_sort_by_input_manager(config) {
23
24
  for (let sort_prepped of sorts_prepped) {
24
25
  sorts.push({
25
26
  is_ascending: sort_prepped?.is_ascending_checkbox_manager?.val,
26
- data_row_variable_path: sort_prepped?.data_row_variable_path_input_manager?.val,
27
+ variable_path: sort_prepped?.variable_path_input_manager?.val,
27
28
  })
28
29
  }
29
30
  }
@@ -34,54 +35,17 @@ export function create_sort_by_input_manager(config) {
34
35
  let sorts_prepped_loc = []
35
36
  if (Array.isArray(sorts)) {
36
37
  for (let i = 0; i < sorts.length; i++) {
37
- let extra_button_manager = $state(null)
38
- let extra_popover_manager = $state(null)
39
- extra_popover_manager = create_popover_manager({
40
- target_width: 200,
41
- target_height: 200,
42
- type: "dropdown",
43
- anchor_id: () => `button_${extra_button_manager?.id}`,
44
- })
45
- extra_button_manager = create_button_manager({
46
- type: "soft",
47
- support_icon: "three_dots",
48
- icon_sw: 60,
49
- is_uniform: true,
50
- popover_target: () => `popover_${extra_popover_manager?.id}`,
51
- })
52
38
  let delete_button_manager = create_button_manager({
53
- type: "soft",
54
- text: "Delete",
39
+ type: "outlined",
40
+ is_uniform: true,
55
41
  support_icon: "x",
56
42
  color: "var(--error-t)",
57
- text_align: "left",
58
43
  on_click: () => {
59
- extra_popover_manager.close()
60
44
  if (Array.isArray(sorts_prepped) && i >= 0 && i < sorts_prepped.length) {
61
45
  sorts_prepped.splice(i, 1)
62
46
  }
63
47
  },
64
48
  })
65
- let shift_up_button_manager = create_button_manager({
66
- type: "soft",
67
- text: "Shift Up",
68
- support_icon: "arrow_tailed",
69
- icon_deg: 270,
70
- text_align: "left",
71
- on_click: () => {
72
- console.log("shift sort up")
73
- },
74
- })
75
- let shift_down_button_manager = create_button_manager({
76
- type: "soft",
77
- text: "Shift Down",
78
- support_icon: "arrow_tailed",
79
- text_align: "left",
80
- icon_deg: 90,
81
- on_click: () => {
82
- console.log("shift sort down")
83
- },
84
- })
85
49
  let is_ascending_checkbox_manager = create_checkbox_manager({
86
50
  type: "toggle",
87
51
  val: sorts?.[i]?.is_ascending ?? null,
@@ -89,27 +53,25 @@ export function create_sort_by_input_manager(config) {
89
53
  console.log("toggle is ascending")
90
54
  },
91
55
  })
92
- let data_row_variable_path_input_manager = create_variable_path_input_manager({
56
+ let variable_path_input_manager = create_variable_path_input_manager({
93
57
  is_popover: false,
94
58
  defined_data_type: row_data_type,
95
59
  get_defined_options: config?.get_defined_options,
96
- val: sorts?.[i]?.data_row_variable_path ?? null,
60
+ val: sorts?.[i]?.variable_path ?? null,
61
+ on_finish: () => variable_path_input_manager.close_popover(),
97
62
  })
98
63
  sorts_prepped_loc.push({
99
64
  ...sorts?.[i],
100
- extra_button_manager: extra_button_manager,
101
- extra_popover_manager: extra_popover_manager,
102
65
  delete_button_manager: delete_button_manager,
103
- shift_up_button_manager: shift_up_button_manager,
104
- shift_down_button_manager: shift_down_button_manager,
105
66
  is_ascending_checkbox_manager: is_ascending_checkbox_manager,
106
- data_row_variable_path_input_manager: data_row_variable_path_input_manager,
67
+ variable_path_input_manager: variable_path_input_manager,
107
68
  })
108
69
  }
109
70
  }
110
71
  sorts_prepped = sorts_prepped_loc
111
72
  }
112
73
 
74
+ let save_server_sort_is_loading = $state(false)
113
75
  function init(config) {
114
76
  popover_manager = create_popover_manager({
115
77
  header: "Sort By",
@@ -124,9 +86,27 @@ export function create_sort_by_input_manager(config) {
124
86
  popover_target: () => `popover_${popover_manager?.id}`,
125
87
  })
126
88
  apply_sorting_button_manager = create_button_manager({
127
- text: "Apply Sorting",
89
+ text: "Apply Local Sort",
128
90
  on_click: () => {
129
- console.log("Apply Sorting")
91
+ if (typeof config?.apply_sort == "function") {
92
+ config?.apply_sort(val)
93
+ }
94
+ },
95
+ })
96
+ save_server_sort_button_manager = create_button_manager({
97
+ type: "outlined",
98
+ text: "Save Server Sort",
99
+ on_click: async () => {
100
+ save_server_sort_is_loading = true
101
+ if (typeof config?.save_server_sort == "function") {
102
+ const res = await config?.save_server_sort(val)
103
+ if (res?.is_success) {
104
+ save_server_sort_button_manager.success_trigger()
105
+ } else {
106
+ save_server_sort_button_manager.error_trigger()
107
+ }
108
+ }
109
+ save_server_sort_is_loading = false
130
110
  },
131
111
  })
132
112
  add_sort_button_manager = create_button_manager({
@@ -139,7 +119,7 @@ export function create_sort_by_input_manager(config) {
139
119
  for (let sort_prepped of sorts_prepped) {
140
120
  sorts.push({
141
121
  is_ascending: sort_prepped?.is_ascending_checkbox_manager?.val,
142
- data_row_variable_path: sort_prepped?.data_row_variable_path_input_manager?.val,
122
+ variable_path: sort_prepped?.variable_path_input_manager?.val,
143
123
  })
144
124
  }
145
125
  }
@@ -147,7 +127,7 @@ export function create_sort_by_input_manager(config) {
147
127
  ...sorts,
148
128
  {
149
129
  is_ascending: false,
150
- data_row_variable_path: null,
130
+ variable_path: null,
151
131
  },
152
132
  ]
153
133
  set_sorts_prepped(sorts)
@@ -180,6 +160,9 @@ export function create_sort_by_input_manager(config) {
180
160
  get apply_sorting_button_manager() {
181
161
  return apply_sorting_button_manager
182
162
  },
163
+ get save_server_sort_button_manager() {
164
+ return save_server_sort_button_manager
165
+ },
183
166
  get sorts_prepped() {
184
167
  return sorts_prepped
185
168
  },
@@ -15,14 +15,11 @@ import {
15
15
  csv_to_json,
16
16
  create_unique_id,
17
17
  set_definition_stack,
18
- set_def,
19
18
  get_def_from_variable_path,
20
19
  variables_data_type_remaining_to_astc,
21
20
  } from "$lib/client/index.js"
22
21
  import { tick } from "svelte"
23
22
  import { browser } from "$app/environment"
24
- // tbd quick sort for column override default sort or work conjuction with
25
- // select bulk rows with condition (eg ["row","points"] greater_than 2000) where
26
23
 
27
24
  export function create_table_advanced_manager(config) {
28
25
  const id = create_unique_id(null, 20)
@@ -62,6 +59,7 @@ export function create_table_advanced_manager(config) {
62
59
  let rows_per_page_dropdown_manager = $state(null)
63
60
  let cur_page = $state(1)
64
61
  let load_more_button_manager = $state(null)
62
+ let sort_by = $state(null)
65
63
  let sort_by_input_manager = $state(null)
66
64
  let is_bulk_select = $state(false)
67
65
  let toggle_bulk_selectable_button_manager = $state(null)
@@ -134,21 +132,45 @@ export function create_table_advanced_manager(config) {
134
132
  table_search_text_input_manager?.val.trim() !== ""
135
133
  ) {
136
134
  for (let i = 0; i < rows_prepped.length; i++) {
137
- if (rows_prepped[i]?.searchable_text.includes(table_search_text_input_manager?.val.toLowerCase())) {
135
+ if (
136
+ rows_prepped[i]?.searchable_text &&
137
+ rows_prepped[i]?.searchable_text.toLowerCase().includes(table_search_text_input_manager.val.toLowerCase())
138
+ ) {
138
139
  row_indexes.push(i)
139
140
  }
140
141
  }
141
142
  } else {
142
143
  row_indexes = Array.isArray(rows_prepped) ? Array.from({ length: rows_prepped.length }, (_, i) => i) : []
143
144
  }
144
- // tbd sort and sub sorts correctly
145
- // if (Array.isArray(sort_by_input_manager?.val)) {
146
- // for (let sort_by_item of sort_by_input_manager?.val) {
147
- // // sort_by_item?.is_ascending
148
- // // sort_by_item?.data_row_variable_path
149
- // // const val_at_path = get_def_from_variable_path(sort_by_item?.data_row_variable_path)
150
- // }
151
- // }
145
+ function get_column_value(row, column_id) {
146
+ const attrs = row?.columns?.[column_id]?.body_content?.attributes ?? {}
147
+ const val_from_variable_path = attrs.val_from_variable_path ?? attrs.content_from_variable_path
148
+ if (val_from_variable_path) {
149
+ return get_def_from_variable_path(val_from_variable_path, [{ row_i: row?.row_i }, ...definition_stack])
150
+ }
151
+ return attrs.val ?? attrs.content ?? null
152
+ }
153
+ if (Array.isArray(sort_by) && sort_by.length > 0) {
154
+ row_indexes.sort((a, b) => {
155
+ for (let sort_item of sort_by) {
156
+ const column_id = sort_item?.variable_path?.[0]
157
+ const is_ascending = !!sort_item?.is_ascending
158
+ let a_val = get_column_value(rows_prepped[a], column_id)
159
+ let b_val = get_column_value(rows_prepped[b], column_id)
160
+ if (a_val === b_val) continue
161
+ if (a_val == null) return is_ascending ? 1 : -1
162
+ if (b_val == null) return is_ascending ? -1 : 1
163
+ if (typeof a_val === "number" && typeof b_val === "number") {
164
+ return is_ascending ? a_val - b_val : b_val - a_val
165
+ }
166
+ const a_str = Array.isArray(a_val) ? a_val.join(",") : String(a_val)
167
+ const b_str = Array.isArray(b_val) ? b_val.join(",") : String(b_val)
168
+ if (a_str === b_str) continue
169
+ return is_ascending ? a_str.localeCompare(b_str) : b_str.localeCompare(a_str)
170
+ }
171
+ return 0
172
+ })
173
+ }
152
174
  return row_indexes
153
175
  }
154
176
 
@@ -166,7 +188,6 @@ export function create_table_advanced_manager(config) {
166
188
  const raf = () => (browser ? new Promise(requestAnimationFrame) : new Promise((r) => setTimeout(r, 0)))
167
189
 
168
190
  async function set_rows_prepped(columns_prepped_input) {
169
- console.log("set_rows_prepped", rows_data)
170
191
  is_loading_rows = true
171
192
  rows_prepped = []
172
193
  loading_rows_progress = 0
@@ -191,7 +212,6 @@ export function create_table_advanced_manager(config) {
191
212
  }
192
213
 
193
214
  function get_row_prepped(columns_prepped_input, row_data, row_i) {
194
- console.log("get_row_prepped", { row_data, row_i, ds: [{ [row_iter_identifier]: row_i }, ...definition_stack] })
195
215
  let searchable_text = ""
196
216
  let columns_prepped_loc = {}
197
217
  if (Array.isArray(column_ids_display_order)) {
@@ -458,7 +478,6 @@ export function create_table_advanced_manager(config) {
458
478
  }
459
479
  )
460
480
  } else {
461
- console.log("insert_column_error_tbd", res)
462
481
  preempt_insert_column_popover_manager.show_temp_message("Error inserting column", "error", 1800, false)
463
482
  }
464
483
  }
@@ -473,7 +492,6 @@ export function create_table_advanced_manager(config) {
473
492
  const path_to_set = [...rows_data_from_variable_path, Number.isInteger(row_i) ? row_i : 0]
474
493
  let editable_row = null
475
494
  if (!Number.isInteger(row_i)) {
476
- console.log("columns_prepped", columns_prepped)
477
495
  editable_row = {}
478
496
  } else {
479
497
  editable_row = get_def_from_variable_path([...rows_data_from_variable_path, row_i], definition_stack)
@@ -508,7 +526,6 @@ export function create_table_advanced_manager(config) {
508
526
  on_click: async () => {
509
527
  upsert_row_is_loading = true
510
528
  const row_data = get_def_from_variable_path([row_edit_def_identifier], row_definition_stack)
511
- console.log("edited_row", { row_i, row_data })
512
529
  if (Number.isInteger(row_i)) {
513
530
  if (typeof config?.on_event == "function") {
514
531
  const res = await config?.on_event({
@@ -544,7 +561,6 @@ export function create_table_advanced_manager(config) {
544
561
  row: row_data,
545
562
  path: path_to_set,
546
563
  })
547
- console.log("insert_row_res", { res, columns_prepped })
548
564
  if (res?.is_success) {
549
565
  preempt_insert_row_popover_manager.show_temp_message(
550
566
  "Successfully inserted row",
@@ -554,7 +570,6 @@ export function create_table_advanced_manager(config) {
554
570
  () => set_rows_prepped(columns_prepped)
555
571
  )
556
572
  } else {
557
- console.log("insert_row_error_tbd", res)
558
573
  preempt_insert_row_popover_manager.show_temp_message("Error insering row", "error", 1800, false)
559
574
  }
560
575
  }
@@ -720,7 +735,6 @@ export function create_table_advanced_manager(config) {
720
735
  }
721
736
 
722
737
  function reset_definition_stack(input) {
723
- console.log("reset_definition_stack", deep_copy(input))
724
738
  definition_stack = input
725
739
  set_rows_prepped(columns_prepped)
726
740
  }
@@ -734,6 +748,7 @@ export function create_table_advanced_manager(config) {
734
748
  table_id = config?.table_id
735
749
  table_name = config?.table_name
736
750
  table_description = config?.table_description
751
+ sort_by = config?.table?.sort_by
737
752
  rows_data_from_variable_path = config?.rows_data_from_variable_path
738
753
  row_iter_identifier = config?.row_iter_identifier ?? "row_i"
739
754
  definition_stack = config?.definition_stack
@@ -785,8 +800,23 @@ export function create_table_advanced_manager(config) {
785
800
  })
786
801
  sort_by_input_manager = create_sort_by_input_manager({
787
802
  is_popover: true,
788
- val: config?.val?.sort_by,
789
- // row_data_type: row_data_type,
803
+ val: sort_by,
804
+ apply_sort: (input) => {
805
+ sort_by = input
806
+ },
807
+ save_server_sort: async (input) => {
808
+ if (typeof config?.on_event == "function") {
809
+ const res = await config?.on_event({
810
+ type: "update_table_server_sort",
811
+ input: input,
812
+ })
813
+ return res
814
+ }
815
+ },
816
+ get_defined_options: () => {
817
+ const defined_options = Object.keys(columns_prepped || {}).map((h) => ({ key: h, name: h }))
818
+ return defined_options
819
+ },
790
820
  })
791
821
  toggle_bulk_selectable_button_manager = create_button_manager({
792
822
  type: "soft",
@@ -977,7 +1007,6 @@ export function create_table_advanced_manager(config) {
977
1007
  }
978
1008
  )
979
1009
  } else {
980
- console.log("update_row_error_tbd", res)
981
1010
  prempt_bulk_upload_rows_popover_manager.show_temp_message("Error bulk inserting rows", "error", 1800, false)
982
1011
  }
983
1012
  }
@@ -2,7 +2,6 @@ import { create_popover_manager } from "$lib/Components/Popover/index.svelte.js"
2
2
  import { create_button_manager } from "$lib/Components/Button/index.svelte.js"
3
3
  import { create_text_input_manager } from "$lib/Components/TextInput/index.svelte.js"
4
4
  import { create_dropdown_manager } from "$lib/Components/Dropdown/index.svelte.js"
5
- import { deep_copy } from "$lib/client/index.js"
6
5
 
7
6
  export function create_variable_path_input_manager(config) {
8
7
  let popover_manager = $state(null)
@@ -23,7 +22,6 @@ export function create_variable_path_input_manager(config) {
23
22
  }
24
23
 
25
24
  function prep_path(input) {
26
- console.log("prep_path", input)
27
25
  let path_prepped_loc = $state([])
28
26
  if (Array.isArray(input)) {
29
27
  let variable_data_type_at_path = Array.isArray(defined_options)
@@ -244,7 +244,7 @@
244
244
  children: [],
245
245
  attributes: {
246
246
  size: 10,
247
- content_from_variable_path: ["variables", "rows", ["loops", 0], "id"],
247
+ content_from_variable_path: ["variables", "rows", ["row_i"], "id"],
248
248
  },
249
249
  selector_id: "hcsqz",
250
250
  },
@@ -268,19 +268,19 @@
268
268
  is_autogenerated: true,
269
269
  is_force_uniqueness: false,
270
270
  },
271
- ttttt: {
271
+ population: {
272
272
  is_fixed: false,
273
273
  is_shown: true,
274
274
  alignment: "left",
275
275
  max_width: 30,
276
276
  min_width: 20,
277
- description: "ffff",
277
+ description: "population",
278
278
  is_nullable: true,
279
279
  body_content: {
280
280
  type_id: "number",
281
281
  children: [],
282
282
  attributes: {
283
- val_from_variable_path: ["rows", ["row_i"], "ttttt"],
283
+ val_from_variable_path: ["rows", ["row_i"], "population"],
284
284
  },
285
285
  selector_id: "vukyefhw",
286
286
  },
@@ -297,7 +297,45 @@
297
297
  type_id: "base_text",
298
298
  children: [],
299
299
  attributes: {
300
- content: "Ttttt",
300
+ content: "Population",
301
+ },
302
+ selector_id: "lpcqsjlq",
303
+ },
304
+ is_primary_key: false,
305
+ is_autogenerated: false,
306
+ is_force_uniqueness: false,
307
+ is_use_in_short_display: false,
308
+ },
309
+ us_state: {
310
+ is_fixed: false,
311
+ is_shown: true,
312
+ alignment: "left",
313
+ max_width: 30,
314
+ min_width: 20,
315
+ description: "us_state",
316
+ is_nullable: true,
317
+ body_content: {
318
+ type_id: "base_text",
319
+ children: [],
320
+ attributes: {
321
+ content_from_variable_path: ["rows", ["row_i"], "us_state"],
322
+ },
323
+ selector_id: "kukyefhw",
324
+ },
325
+ db_data_type: {
326
+ type: "text_literal",
327
+ attributes: {},
328
+ },
329
+ is_db_column: true,
330
+ is_updatable: false,
331
+ default_value: null,
332
+ display_order: 2,
333
+ postgres_type: "text",
334
+ header_content: {
335
+ type_id: "base_text",
336
+ children: [],
337
+ attributes: {
338
+ content: "US State",
301
339
  },
302
340
  selector_id: "lpcqsjlq",
303
341
  },
@@ -319,7 +357,7 @@
319
357
  children: [],
320
358
  attributes: {
321
359
  format: "epoch",
322
- val_from_variable_path: ["variables", "rows", ["loops", 0], "db_epoch_created"],
360
+ val_from_variable_path: ["variables", "rows", ["row_i"], "db_epoch_created"],
323
361
  },
324
362
  selector_id: "time_urzjm",
325
363
  },
@@ -329,7 +367,7 @@
329
367
  },
330
368
  is_db_column: true,
331
369
  default_value: null,
332
- display_order: 2,
370
+ display_order: 3,
333
371
  postgres_type: "bigint",
334
372
  header_content: {
335
373
  type_id: "base_text",
@@ -356,7 +394,7 @@
356
394
  children: [],
357
395
  attributes: {
358
396
  format: "epoch",
359
- val_from_variable_path: ["variables", "rows", ["loops", 0], "db_epoch_updated"],
397
+ val_from_variable_path: ["variables", "rows", ["row_i"], "db_epoch_updated"],
360
398
  },
361
399
  selector_id: "epoch_rozyy",
362
400
  },
@@ -366,7 +404,7 @@
366
404
  },
367
405
  is_db_column: true,
368
406
  default_value: null,
369
- display_order: 3,
407
+ display_order: 4,
370
408
  postgres_type: "bigint",
371
409
  header_content: {
372
410
  type_id: "base_text",
@@ -390,7 +428,13 @@
390
428
  })
391
429
 
392
430
  let table_manager = $state(null)
393
- let variables = $state({ rows: data?.rows })
431
+ let variables = $state({
432
+ rows: [
433
+ { us_state: "cccc", population: 200 },
434
+ { us_state: "zzzz", population: 20 },
435
+ { us_state: "aaaaa", population: 400 },
436
+ ],
437
+ })
394
438
 
395
439
  table_manager = create_table_advanced_manager({
396
440
  table_id: "abcdefg",