@dou-ui/dashboard 0.1.0-alpha.3 → 0.1.0-alpha.5

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 (97) hide show
  1. package/dist/chart/chart-settings.js.map +1 -1
  2. package/dist/chart/chart-settings.vue_vue_type_script_setup_true_lang.js +10 -8
  3. package/dist/chart/chart-settings.vue_vue_type_script_setup_true_lang.js.map +1 -1
  4. package/dist/chart/chart.js.map +1 -1
  5. package/dist/chart/chart.vue_vue_type_script_setup_true_lang.js +19 -15
  6. package/dist/chart/chart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/chart/read-props.js +26 -0
  8. package/dist/chart/read-props.js.map +1 -0
  9. package/dist/core/document.js +10 -1
  10. package/dist/core/document.js.map +1 -1
  11. package/dist/core/history.js +23 -0
  12. package/dist/core/history.js.map +1 -1
  13. package/dist/core/transaction.js +8 -2
  14. package/dist/core/transaction.js.map +1 -1
  15. package/dist/dashboard/comment-button.js +6 -0
  16. package/dist/dashboard/comment-button.js.map +1 -0
  17. package/dist/dashboard/comment-button.vue_vue_type_script_setup_true_lang.js +59 -0
  18. package/dist/dashboard/comment-button.vue_vue_type_script_setup_true_lang.js.map +1 -0
  19. package/dist/dashboard/comment-card.js +6 -0
  20. package/dist/dashboard/comment-card.js.map +1 -0
  21. package/dist/dashboard/comment-card.vue_vue_type_script_setup_true_lang.js +128 -0
  22. package/dist/dashboard/comment-card.vue_vue_type_script_setup_true_lang.js.map +1 -0
  23. package/dist/dashboard/comments.js +144 -0
  24. package/dist/dashboard/comments.js.map +1 -0
  25. package/dist/dashboard/dashboard.js.map +1 -1
  26. package/dist/dashboard/dashboard.vue_vue_type_script_setup_true_lang.js +132 -20
  27. package/dist/dashboard/dashboard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/dashboard/error-boundary.js +64 -0
  29. package/dist/dashboard/error-boundary.js.map +1 -0
  30. package/dist/dashboard/frame-context.js.map +1 -1
  31. package/dist/dashboard/widget-body.js.map +1 -1
  32. package/dist/dashboard/widget-body.vue_vue_type_script_setup_true_lang.js +53 -12
  33. package/dist/dashboard/widget-body.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/dashboard/widget-frame.js.map +1 -1
  35. package/dist/dashboard/widget-frame.vue_vue_type_script_setup_true_lang.js +14 -2
  36. package/dist/dashboard/widget-frame.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/dashboard/widget-settings.js.map +1 -1
  38. package/dist/dashboard/widget-settings.vue_vue_type_script_setup_true_lang.js +31 -5
  39. package/dist/dashboard/widget-settings.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/locale.js +12 -0
  42. package/dist/locale.js.map +1 -1
  43. package/dist/pivot/pivot-settings.js.map +1 -1
  44. package/dist/pivot/pivot-settings.vue_vue_type_script_setup_true_lang.js +6 -4
  45. package/dist/pivot/pivot-settings.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/pivot/pivot.js.map +1 -1
  47. package/dist/pivot/pivot.vue_vue_type_script_setup_true_lang.js +4 -2
  48. package/dist/pivot/pivot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/pivot/read-props.js +44 -0
  50. package/dist/pivot/read-props.js.map +1 -0
  51. package/dist/style.css +1 -1
  52. package/dist/style.js +2 -3
  53. package/dist/types/chart/read-props.d.ts +3 -0
  54. package/dist/types/core/document.d.ts +3 -2
  55. package/dist/types/core/history.d.ts +7 -1
  56. package/dist/types/core/transaction.d.ts +10 -1
  57. package/dist/types/core/types.d.ts +5 -0
  58. package/dist/types/dashboard/comment-button.vue.d.ts +15 -0
  59. package/dist/types/dashboard/comment-card.vue.d.ts +13 -0
  60. package/dist/types/dashboard/comments.d.ts +44 -0
  61. package/dist/types/dashboard/dashboard.vue.d.ts +12 -0
  62. package/dist/types/dashboard/error-boundary.d.ts +12 -0
  63. package/dist/types/dashboard/frame-context.d.ts +4 -0
  64. package/dist/types/dashboard/types.d.ts +47 -0
  65. package/dist/types/dashboard/widget-body.vue.d.ts +2 -0
  66. package/dist/types/dashboard/widget-settings.vue.d.ts +4 -0
  67. package/dist/types/index.d.ts +22 -1
  68. package/dist/types/locale.d.ts +8 -0
  69. package/dist/types/pivot/read-props.d.ts +3 -0
  70. package/dist/types/widgets/index.d.ts +1 -1
  71. package/dist/types/widgets/read-props.d.ts +4 -0
  72. package/dist/types/widgets/shared.d.ts +20 -4
  73. package/dist/widgets/index.js +2 -2
  74. package/dist/widgets/index.js.map +1 -1
  75. package/dist/widgets/read-props.js +52 -0
  76. package/dist/widgets/read-props.js.map +1 -0
  77. package/dist/widgets/shared.js +27 -5
  78. package/dist/widgets/shared.js.map +1 -1
  79. package/dist/widgets/stat-settings.js.map +1 -1
  80. package/dist/widgets/stat-settings.vue_vue_type_script_setup_true_lang.js +12 -10
  81. package/dist/widgets/stat-settings.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/widgets/stat.js.map +1 -1
  83. package/dist/widgets/stat.vue_vue_type_script_setup_true_lang.js +10 -13
  84. package/dist/widgets/stat.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/widgets/table-settings.js.map +1 -1
  86. package/dist/widgets/table-settings.vue_vue_type_script_setup_true_lang.js +6 -4
  87. package/dist/widgets/table-settings.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/widgets/table.js.map +1 -1
  89. package/dist/widgets/table.vue_vue_type_script_setup_true_lang.js +3 -1
  90. package/dist/widgets/table.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/widgets/text-settings.js.map +1 -1
  92. package/dist/widgets/text-settings.vue_vue_type_script_setup_true_lang.js +5 -3
  93. package/dist/widgets/text-settings.vue_vue_type_script_setup_true_lang.js.map +1 -1
  94. package/dist/widgets/text.js.map +1 -1
  95. package/dist/widgets/text.vue_vue_type_script_setup_true_lang.js +5 -3
  96. package/dist/widgets/text.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"stat-settings.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","SourceField","_createBlock","FieldSelect","_unref","SettingsField","_withCtx","_createElementVNode","_Fragment","_createCommentVNode"],"sources":["../../src/widgets/stat-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouInput, DouInputNumber } from 'dou-ui'\nimport { computed } from 'vue'\nimport { useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport FieldSelect from './field-select.vue'\nimport SettingsField from './settings-field.vue'\nimport { fieldsOf } from './shared'\nimport SourceField from './source-field.vue'\nimport type { StatWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardStatSettings' })\n\nconst model = defineModel<StatWidgetProps>({ required: true })\nconst messages = useDashboardMessages()\nconst { data } = useDashboardWidget()\nconst fields = computed(() => fieldsOf(data.value))\nconst set = (patch: Partial<StatWidgetProps>) => (model.value = { ...model.value, ...patch })\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SourceField\n :model-value=\"model.source\"\n optional\n @update:model-value=\"(source) => set({ source })\"\n />\n <FieldSelect\n v-if=\"model.source\"\n :model-value=\"model.field\"\n :label=\"messages.value\"\n :fields=\"fields\"\n @update:model-value=\"(field) => set({ field: field as string | undefined })\"\n />\n <SettingsField v-else :label=\"messages.value\">\n <DouInputNumber\n :model-value=\"model.value ?? null\"\n :aria-label=\"messages.value\"\n @update:model-value=\"(value) => set({ value: value ?? undefined })\"\n />\n </SettingsField>\n <div class=\"dou-dashboard__field-row\">\n <SettingsField :label=\"messages.prefix\">\n <DouInput\n :model-value=\"model.prefix ?? ''\"\n :aria-label=\"messages.prefix\"\n @update:model-value=\"(prefix) => set({ prefix: prefix || undefined })\"\n />\n </SettingsField>\n <SettingsField :label=\"messages.suffix\">\n <DouInput\n :model-value=\"model.suffix ?? ''\"\n :aria-label=\"messages.suffix\"\n @update:model-value=\"(suffix) => set({ suffix: suffix || undefined })\"\n />\n </SettingsField>\n </div>\n <SettingsField :label=\"messages.precision\">\n <DouInputNumber\n :model-value=\"model.precision ?? null\"\n :min=\"0\"\n :max=\"6\"\n :aria-label=\"messages.precision\"\n @update:model-value=\"(precision) => set({ precision: precision ?? undefined })\"\n />\n </SettingsField>\n <template v-if=\"model.source\">\n <FieldSelect\n :model-value=\"model.trend\"\n :label=\"messages.trend\"\n :fields=\"fields\"\n @update:model-value=\"(trend) => set({ trend: trend as string | undefined })\"\n />\n <FieldSelect\n :model-value=\"model.delta\"\n :label=\"messages.delta\"\n :fields=\"fields\"\n @update:model-value=\"(delta) => set({ delta: delta as string | undefined })\"\n />\n </template>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAaA,MAAM,QAAQA,SAA4B,SAAA,YAAmB;EAC7D,MAAM,WAAW,qBAAqB;EACtC,MAAM,EAAE,SAAS,mBAAmB;EACpC,MAAM,SAAS,eAAe,SAAS,KAAK,KAAK,CAAC;EAClD,MAAM,OAAO,UAAqC,MAAM,QAAQ;GAAE,GAAG,MAAM;GAAO,GAAG;EAAM;;GAIzF,OAAAC,UAAA,GAAAC,mBA2DM,OA3DN,YA2DM;IA1DJC,YAIEC,sBAAA;KAHC,eAAa,MAAA,MAAM;KACpB,UAAA;KACC,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAW,IAAG,EAAG,OAAM,CAAA;;IAGvC,MAAA,MAAM,UADdH,UAAA,GAAAI,YAMEC,sBAAA;;KAJC,eAAa,MAAA,MAAM;KACnB,OAAOC,MAAA,QAAA,CAAQ,CAAC;KAChB,QAAQ,OAAA;KACR,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAU,MAAK,CAAA;;;;;I,OAEpDN,UAAA,GAAAI,YAMgBG,wBAAA;;KANO,OAAOD,MAAA,QAAA,CAAQ,CAAC;;KACrC,SAAAE,cAIE,CAJFN,YAIEI,MAAA,cAAA,GAAA;MAHC,eAAa,MAAA,MAAM,SAAK;MACxB,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAA,OAAU,SAAS,KAAA,EAAS,CAAA;;;;IAGnEG,mBAeM,OAfN,YAeM,CAdJP,YAMgBK,wBAAA,EANA,OAAOD,MAAA,QAAA,CAAQ,CAAC,O;KAC9B,SAAAE,cAIE,CAJFN,YAIEI,MAAA,QAAA,GAAA;MAHC,eAAa,MAAA,MAAM,UAAM;MACzB,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAW,IAAG,EAAA,QAAW,UAAU,KAAA,EAAS,CAAA;;;I,kBAGtEJ,YAMgBK,wBAAA,EANA,OAAOD,MAAA,QAAA,CAAQ,CAAC,O;KAC9B,SAAAE,cAIE,CAJFN,YAIEI,MAAA,QAAA,GAAA;MAHC,eAAa,MAAA,MAAM,UAAM;MACzB,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAW,IAAG,EAAA,QAAW,UAAU,KAAA,EAAS,CAAA;;;;IAIxEJ,YAQgBK,wBAAA,EARA,OAAOD,MAAA,QAAA,CAAQ,CAAC,U;KAC9B,SAAAE,cAME,CANFN,YAMEI,MAAA,cAAA,GAAA;MALC,eAAa,MAAA,MAAM,aAAS;MAC5B,KAAK;MACL,KAAK;MACL,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,cAAc,IAAG,EAAA,WAAc,aAAa,KAAA,EAAS,CAAA;;;;IAG/D,MAAA,MAAM,UAAtBN,UAAA,GAAAC,mBAaWS,UAAA,EAAA,KAAA,EAAA,GAAA,CAZTR,YAKEG,sBAAA;KAJC,eAAa,MAAA,MAAM;KACnB,OAAOC,MAAA,QAAA,CAAQ,CAAC;KAChB,QAAQ,OAAA;KACR,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAU,MAAK,CAAA;;;;;I,IAEpDJ,YAKEG,sBAAA;KAJC,eAAa,MAAA,MAAM;KACnB,OAAOC,MAAA,QAAA,CAAQ,CAAC;KAChB,QAAQ,OAAA;KACR,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAU,MAAK,CAAA"}
1
+ {"version":3,"file":"stat-settings.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","SourceField","_createBlock","FieldSelect","_unref","SettingsField","_withCtx","_createElementVNode","_Fragment","_createCommentVNode"],"sources":["../../src/widgets/stat-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouInput, DouInputNumber } from 'dou-ui'\nimport { computed } from 'vue'\nimport { useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport FieldSelect from './field-select.vue'\nimport SettingsField from './settings-field.vue'\nimport { fieldsOf } from './shared'\nimport SourceField from './source-field.vue'\nimport type { StatWidgetProps } from './types'\nimport { statPropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardStatSettings' })\n\nconst model = defineModel<StatWidgetProps>({ required: true })\n// the props as saved may have the wrong types: read them as the widget does\nconst view = computed(() => statPropsOf(model.value as Record<string, unknown>))\nconst messages = useDashboardMessages()\nconst { data } = useDashboardWidget()\nconst fields = computed(() => fieldsOf(data.value))\nconst set = (patch: Partial<StatWidgetProps>) => (model.value = { ...model.value, ...patch })\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SourceField\n :model-value=\"view.source\"\n optional\n @update:model-value=\"(source) => set({ source })\"\n />\n <FieldSelect\n v-if=\"view.source\"\n :model-value=\"view.field\"\n :label=\"messages.value\"\n :fields=\"fields\"\n @update:model-value=\"(field) => set({ field: field as string | undefined })\"\n />\n <SettingsField v-else :label=\"messages.value\">\n <DouInputNumber\n :model-value=\"view.value ?? null\"\n :aria-label=\"messages.value\"\n @update:model-value=\"(value) => set({ value: value ?? undefined })\"\n />\n </SettingsField>\n <div class=\"dou-dashboard__field-row\">\n <SettingsField :label=\"messages.prefix\">\n <DouInput\n :model-value=\"view.prefix ?? ''\"\n :aria-label=\"messages.prefix\"\n @update:model-value=\"(prefix) => set({ prefix: prefix || undefined })\"\n />\n </SettingsField>\n <SettingsField :label=\"messages.suffix\">\n <DouInput\n :model-value=\"view.suffix ?? ''\"\n :aria-label=\"messages.suffix\"\n @update:model-value=\"(suffix) => set({ suffix: suffix || undefined })\"\n />\n </SettingsField>\n </div>\n <SettingsField :label=\"messages.precision\">\n <DouInputNumber\n :model-value=\"view.precision ?? null\"\n :min=\"0\"\n :max=\"6\"\n :aria-label=\"messages.precision\"\n @update:model-value=\"(precision) => set({ precision: precision ?? undefined })\"\n />\n </SettingsField>\n <template v-if=\"view.source\">\n <FieldSelect\n :model-value=\"view.trend\"\n :label=\"messages.trend\"\n :fields=\"fields\"\n @update:model-value=\"(trend) => set({ trend: trend as string | undefined })\"\n />\n <FieldSelect\n :model-value=\"view.delta\"\n :label=\"messages.delta\"\n :fields=\"fields\"\n @update:model-value=\"(delta) => set({ delta: delta as string | undefined })\"\n />\n </template>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAcA,MAAM,QAAQA,SAA4B,SAAA,YAAmB;EAE7D,MAAM,OAAO,eAAe,YAAY,MAAM,KAAgC,CAAC;EAC/E,MAAM,WAAW,qBAAqB;EACtC,MAAM,EAAE,SAAS,mBAAmB;EACpC,MAAM,SAAS,eAAe,SAAS,KAAK,KAAK,CAAC;EAClD,MAAM,OAAO,UAAqC,MAAM,QAAQ;GAAE,GAAG,MAAM;GAAO,GAAG;EAAM;;GAIzF,OAAAC,UAAA,GAAAC,mBA2DM,OA3DN,YA2DM;IA1DJC,YAIEC,sBAAA;KAHC,eAAa,KAAA,MAAK;KACnB,UAAA;KACC,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAW,IAAG,EAAG,OAAM,CAAA;;IAGvC,KAAA,MAAK,UADbH,UAAA,GAAAI,YAMEC,sBAAA;;KAJC,eAAa,KAAA,MAAK;KAClB,OAAOC,MAAA,QAAA,CAAQ,CAAC;KAChB,QAAQ,OAAA;KACR,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAU,MAAK,CAAA;;;;;I,OAEpDN,UAAA,GAAAI,YAMgBG,wBAAA;;KANO,OAAOD,MAAA,QAAA,CAAQ,CAAC;;KACrC,SAAAE,cAIE,CAJFN,YAIEI,MAAA,cAAA,GAAA;MAHC,eAAa,KAAA,MAAK,SAAK;MACvB,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAA,OAAU,SAAS,KAAA,EAAS,CAAA;;;;IAGnEG,mBAeM,OAfN,YAeM,CAdJP,YAMgBK,wBAAA,EANA,OAAOD,MAAA,QAAA,CAAQ,CAAC,O;KAC9B,SAAAE,cAIE,CAJFN,YAIEI,MAAA,QAAA,GAAA;MAHC,eAAa,KAAA,MAAK,UAAM;MACxB,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAW,IAAG,EAAA,QAAW,UAAU,KAAA,EAAS,CAAA;;;I,kBAGtEJ,YAMgBK,wBAAA,EANA,OAAOD,MAAA,QAAA,CAAQ,CAAC,O;KAC9B,SAAAE,cAIE,CAJFN,YAIEI,MAAA,QAAA,GAAA;MAHC,eAAa,KAAA,MAAK,UAAM;MACxB,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAW,IAAG,EAAA,QAAW,UAAU,KAAA,EAAS,CAAA;;;;IAIxEJ,YAQgBK,wBAAA,EARA,OAAOD,MAAA,QAAA,CAAQ,CAAC,U;KAC9B,SAAAE,cAME,CANFN,YAMEI,MAAA,cAAA,GAAA;MALC,eAAa,KAAA,MAAK,aAAS;MAC3B,KAAK;MACL,KAAK;MACL,cAAYA,MAAA,QAAA,CAAQ,CAAC;MACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,cAAc,IAAG,EAAA,WAAc,aAAa,KAAA,EAAS,CAAA;;;;IAG/D,KAAA,MAAK,UAArBN,UAAA,GAAAC,mBAaWS,UAAA,EAAA,KAAA,EAAA,GAAA,CAZTR,YAKEG,sBAAA;KAJC,eAAa,KAAA,MAAK;KAClB,OAAOC,MAAA,QAAA,CAAQ,CAAC;KAChB,QAAQ,OAAA;KACR,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAU,MAAK,CAAA;;;;;I,IAEpDJ,YAKEG,sBAAA;KAJC,eAAa,KAAA,MAAK;KAClB,OAAOC,MAAA,QAAA,CAAQ,CAAC;KAChB,QAAQ,OAAA;KACR,uBAAkB,OAAA,OAAA,OAAA,MAAG,UAAU,IAAG,EAAU,MAAK,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"stat.js","names":["_sfc_main"],"sources":["../../src/widgets/stat.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSparkline, DouStatistic } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport { valueAt } from './shared'\nimport type { StatWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardStatWidget' })\n\nconst { props, data, size } = useDashboardWidget<StatWidgetProps>()\nconst messages = useDashboardMessages()\n\nconst value = computed(() => {\n const { field, value: fixed } = props.value\n if (!field) return fixed ?? null\n const read = Number(valueAt(data.value, field))\n return Number.isFinite(read) ? read : null\n})\nconst delta = computed(() => {\n const read = props.value.delta ? Number(valueAt(data.value, props.value.delta)) : Number.NaN\n return Number.isFinite(read) ? read : undefined\n})\nconst deltaText = computed(() => {\n if (delta.value === undefined) return ''\n const percent = `${delta.value > 0 ? '+' : ''}${(delta.value * 100).toFixed(1)}%`\n return format(messages.value.deltaText, { value: percent })\n})\nconst points = computed(() => {\n const list = props.value.trend ? valueAt(data.value, props.value.trend) : undefined\n return Array.isArray(list) ? list.map(Number).filter(Number.isFinite) : []\n})\n/** The sparkline takes what the number leaves of the height, out to the card's edges. */\nconst sparkHeight = computed(() => Math.max(0, Math.floor(size.height.value - 56)))\n</script>\n\n<template>\n <div class=\"dou-dashboard-stat\">\n <DouStatistic\n :value=\"value\"\n :precision=\"props.precision\"\n :prefix=\"props.prefix\"\n :suffix=\"props.suffix\"\n :trend=\"delta === undefined || delta === 0 ? undefined : delta > 0 ? 'up' : 'down'\"\n >\n <template v-if=\"deltaText\" #footer>{{ deltaText }}</template>\n </DouStatistic>\n <div v-if=\"points.length > 1 && sparkHeight >= 24\" class=\"dou-dashboard-stat__spark\">\n <DouSparkline\n :data=\"points\"\n type=\"area\"\n smooth\n :width=\"size.width.value + 32\"\n :height=\"sparkHeight\"\n />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"stat.js","names":["_sfc_main"],"sources":["../../src/widgets/stat.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSparkline, DouStatistic } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport { statPropsOf } from './read-props'\nimport { numberOf, valueAt } from './shared'\n\ndefineOptions({ name: 'DouDashboardStatWidget' })\n\nconst { props: raw, data, size } = useDashboardWidget()\nconst props = computed(() => statPropsOf(raw.value))\nconst messages = useDashboardMessages()\n\n// a fixed value and one read from the data follow the same rule: a number, or text that is one\nconst value = computed(() => {\n const { field, value: fixed } = props.value\n return (field ? numberOf(valueAt(data.value, field)) : fixed) ?? null\n})\nconst delta = computed(() =>\n props.value.delta ? numberOf(valueAt(data.value, props.value.delta)) : undefined,\n)\nconst deltaText = computed(() => {\n if (delta.value === undefined) return ''\n const percent = `${delta.value > 0 ? '+' : ''}${(delta.value * 100).toFixed(1)}%`\n return format(messages.value.deltaText, { value: percent })\n})\nconst points = computed(() => {\n const list = props.value.trend ? valueAt(data.value, props.value.trend) : undefined\n return Array.isArray(list) ? list.map(numberOf).filter((n): n is number => n !== undefined) : []\n})\n/** The sparkline takes what the number leaves of the height, out to the card's edges. */\nconst sparkHeight = computed(() => Math.max(0, Math.floor(size.height.value - 56)))\n</script>\n\n<template>\n <div class=\"dou-dashboard-stat\">\n <DouStatistic\n :value=\"value\"\n :precision=\"props.precision\"\n :prefix=\"props.prefix\"\n :suffix=\"props.suffix\"\n :trend=\"delta === undefined || delta === 0 ? undefined : delta > 0 ? 'up' : 'down'\"\n >\n <template v-if=\"deltaText\" #footer>{{ deltaText }}</template>\n </DouStatistic>\n <div v-if=\"points.length > 1 && sparkHeight >= 24\" class=\"dou-dashboard-stat__spark\">\n <DouSparkline\n :data=\"points\"\n type=\"area\"\n smooth\n :width=\"size.width.value + 32\"\n :height=\"sparkHeight\"\n />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,6 +1,7 @@
1
1
  import { format, useDashboardMessages } from "../locale.js";
2
2
  import { useDashboardWidget } from "../widget/context.js";
3
- import { valueAt } from "./shared.js";
3
+ import { numberOf, valueAt } from "./shared.js";
4
+ import { statPropsOf } from "./read-props.js";
4
5
  import { DouSparkline, DouStatistic } from "dou-ui";
5
6
  import { computed, createCommentVNode, createElementBlock, createSlots, createTextVNode, createVNode, defineComponent, openBlock, toDisplayString, unref, withCtx } from "vue";
6
7
  // src/widgets/stat.vue?vue&type=script&setup=true&lang.ts
@@ -13,18 +14,14 @@ var stat_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
13
14
  name: "DouDashboardStatWidget",
14
15
  __name: "stat",
15
16
  setup(__props) {
16
- const { props, data, size } = useDashboardWidget();
17
+ const { props: raw, data, size } = useDashboardWidget();
18
+ const props = computed(() => statPropsOf(raw.value));
17
19
  const messages = useDashboardMessages();
18
20
  const value = computed(() => {
19
21
  const { field, value: fixed } = props.value;
20
- if (!field) return fixed ?? null;
21
- const read = Number(valueAt(data.value, field));
22
- return Number.isFinite(read) ? read : null;
23
- });
24
- const delta = computed(() => {
25
- const read = props.value.delta ? Number(valueAt(data.value, props.value.delta)) : NaN;
26
- return Number.isFinite(read) ? read : void 0;
22
+ return (field ? numberOf(valueAt(data.value, field)) : fixed) ?? null;
27
23
  });
24
+ const delta = computed(() => props.value.delta ? numberOf(valueAt(data.value, props.value.delta)) : void 0);
28
25
  const deltaText = computed(() => {
29
26
  if (delta.value === void 0) return "";
30
27
  const percent = `${delta.value > 0 ? "+" : ""}${(delta.value * 100).toFixed(1)}%`;
@@ -32,16 +29,16 @@ var stat_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
32
29
  });
33
30
  const points = computed(() => {
34
31
  const list = props.value.trend ? valueAt(data.value, props.value.trend) : void 0;
35
- return Array.isArray(list) ? list.map(Number).filter(Number.isFinite) : [];
32
+ return Array.isArray(list) ? list.map(numberOf).filter((n) => n !== void 0) : [];
36
33
  });
37
34
  /** The sparkline takes what the number leaves of the height, out to the card's edges. */
38
35
  const sparkHeight = computed(() => Math.max(0, Math.floor(size.height.value - 56)));
39
36
  return (_ctx, _cache) => {
40
37
  return openBlock(), createElementBlock("div", _hoisted_1, [createVNode(unref(DouStatistic), {
41
38
  value: value.value,
42
- precision: unref(props).precision,
43
- prefix: unref(props).prefix,
44
- suffix: unref(props).suffix,
39
+ precision: props.value.precision,
40
+ prefix: props.value.prefix,
41
+ suffix: props.value.suffix,
45
42
  trend: delta.value === void 0 || delta.value === 0 ? void 0 : delta.value > 0 ? "up" : "down"
46
43
  }, createSlots({ _: 2 }, [deltaText.value ? {
47
44
  name: "footer",
@@ -1 +1 @@
1
- {"version":3,"file":"stat.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_unref","_createSlots","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode"],"sources":["../../src/widgets/stat.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSparkline, DouStatistic } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport { valueAt } from './shared'\nimport type { StatWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardStatWidget' })\n\nconst { props, data, size } = useDashboardWidget<StatWidgetProps>()\nconst messages = useDashboardMessages()\n\nconst value = computed(() => {\n const { field, value: fixed } = props.value\n if (!field) return fixed ?? null\n const read = Number(valueAt(data.value, field))\n return Number.isFinite(read) ? read : null\n})\nconst delta = computed(() => {\n const read = props.value.delta ? Number(valueAt(data.value, props.value.delta)) : Number.NaN\n return Number.isFinite(read) ? read : undefined\n})\nconst deltaText = computed(() => {\n if (delta.value === undefined) return ''\n const percent = `${delta.value > 0 ? '+' : ''}${(delta.value * 100).toFixed(1)}%`\n return format(messages.value.deltaText, { value: percent })\n})\nconst points = computed(() => {\n const list = props.value.trend ? valueAt(data.value, props.value.trend) : undefined\n return Array.isArray(list) ? list.map(Number).filter(Number.isFinite) : []\n})\n/** The sparkline takes what the number leaves of the height, out to the card's edges. */\nconst sparkHeight = computed(() => Math.max(0, Math.floor(size.height.value - 56)))\n</script>\n\n<template>\n <div class=\"dou-dashboard-stat\">\n <DouStatistic\n :value=\"value\"\n :precision=\"props.precision\"\n :prefix=\"props.prefix\"\n :suffix=\"props.suffix\"\n :trend=\"delta === undefined || delta === 0 ? undefined : delta > 0 ? 'up' : 'down'\"\n >\n <template v-if=\"deltaText\" #footer>{{ deltaText }}</template>\n </DouStatistic>\n <div v-if=\"points.length > 1 && sparkHeight >= 24\" class=\"dou-dashboard-stat__spark\">\n <DouSparkline\n :data=\"points\"\n type=\"area\"\n smooth\n :width=\"size.width.value + 32\"\n :height=\"sparkHeight\"\n />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;EAUA,MAAM,EAAE,OAAO,MAAM,SAAS,mBAAoC;EAClE,MAAM,WAAW,qBAAqB;EAEtC,MAAM,QAAQ,eAAe;GAC3B,MAAM,EAAE,OAAO,OAAO,UAAU,MAAM;GACtC,IAAI,CAAC,OAAO,OAAO,SAAS;GAC5B,MAAM,OAAO,OAAO,QAAQ,KAAK,OAAO,KAAK,CAAC;GAC9C,OAAO,OAAO,SAAS,IAAI,IAAI,OAAO;EACxC,CAAC;EACD,MAAM,QAAQ,eAAe;GAC3B,MAAM,OAAO,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,MAAM,MAAM,KAAK,CAAC,IAAI;GAClF,OAAO,OAAO,SAAS,IAAI,IAAI,OAAO,KAAA;EACxC,CAAC;EACD,MAAM,YAAY,eAAe;GAC/B,IAAI,MAAM,UAAU,KAAA,GAAW,OAAO;GACtC,MAAM,UAAU,GAAG,MAAM,QAAQ,IAAI,MAAM,MAAM,MAAM,QAAQ,IAAA,CAAK,QAAQ,CAAC,EAAE;GAC/E,OAAO,OAAO,SAAS,MAAM,WAAW,EAAE,OAAO,QAAQ,CAAC;EAC5D,CAAC;EACD,MAAM,SAAS,eAAe;GAC5B,MAAM,OAAO,MAAM,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM,MAAM,KAAK,IAAI,KAAA;GAC1E,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,MAAM,CAAC,CAAC,OAAO,OAAO,QAAQ,IAAI,CAAC;EAC3E,CAAC;;EAED,MAAM,cAAc,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC;;GAIhF,OAAAA,UAAA,GAAAC,mBAmBM,OAnBN,YAmBM,CAlBJC,YAQeC,MAAA,YAAA,GAAA;IAPZ,OAAO,MAAA;IACP,WAAWA,MAAA,KAAA,CAAK,CAAC;IACjB,QAAQA,MAAA,KAAA,CAAK,CAAC;IACd,QAAQA,MAAA,KAAA,CAAK,CAAC;IACd,OAAO,MAAA,UAAU,KAAA,KAAa,MAAA,UAAK,IAAS,KAAA,IAAY,MAAA,QAAK,IAAA,OAAA;G,0BAE9C,UAAA,Q;IAAY,MAAA;IAAO,IAAAE,cAAe,CAAZC,gBAAAC,gBAAA,UAAA,KAAS,GAAA,CAAA,C;;;;;;;;G,IAEtC,OAAA,MAAO,SAAM,KAAQ,YAAA,SAAW,MAA3CP,UAAA,GAAAC,mBAQM,OARN,YAQM,CAPJC,YAMEC,MAAA,YAAA,GAAA;IALC,MAAM,OAAA;IACP,MAAK;IACL,QAAA;IACC,OAAOA,MAAA,IAAA,CAAI,CAAC,MAAM,QAAK;IACvB,QAAQ,YAAA"}
1
+ {"version":3,"file":"stat.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_unref","_createSlots","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode"],"sources":["../../src/widgets/stat.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSparkline, DouStatistic } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport { statPropsOf } from './read-props'\nimport { numberOf, valueAt } from './shared'\n\ndefineOptions({ name: 'DouDashboardStatWidget' })\n\nconst { props: raw, data, size } = useDashboardWidget()\nconst props = computed(() => statPropsOf(raw.value))\nconst messages = useDashboardMessages()\n\n// a fixed value and one read from the data follow the same rule: a number, or text that is one\nconst value = computed(() => {\n const { field, value: fixed } = props.value\n return (field ? numberOf(valueAt(data.value, field)) : fixed) ?? null\n})\nconst delta = computed(() =>\n props.value.delta ? numberOf(valueAt(data.value, props.value.delta)) : undefined,\n)\nconst deltaText = computed(() => {\n if (delta.value === undefined) return ''\n const percent = `${delta.value > 0 ? '+' : ''}${(delta.value * 100).toFixed(1)}%`\n return format(messages.value.deltaText, { value: percent })\n})\nconst points = computed(() => {\n const list = props.value.trend ? valueAt(data.value, props.value.trend) : undefined\n return Array.isArray(list) ? list.map(numberOf).filter((n): n is number => n !== undefined) : []\n})\n/** The sparkline takes what the number leaves of the height, out to the card's edges. */\nconst sparkHeight = computed(() => Math.max(0, Math.floor(size.height.value - 56)))\n</script>\n\n<template>\n <div class=\"dou-dashboard-stat\">\n <DouStatistic\n :value=\"value\"\n :precision=\"props.precision\"\n :prefix=\"props.prefix\"\n :suffix=\"props.suffix\"\n :trend=\"delta === undefined || delta === 0 ? undefined : delta > 0 ? 'up' : 'down'\"\n >\n <template v-if=\"deltaText\" #footer>{{ deltaText }}</template>\n </DouStatistic>\n <div v-if=\"points.length > 1 && sparkHeight >= 24\" class=\"dou-dashboard-stat__spark\">\n <DouSparkline\n :data=\"points\"\n type=\"area\"\n smooth\n :width=\"size.width.value + 32\"\n :height=\"sparkHeight\"\n />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAUA,MAAM,EAAE,OAAO,KAAK,MAAM,SAAS,mBAAmB;EACtD,MAAM,QAAQ,eAAe,YAAY,IAAI,KAAK,CAAC;EACnD,MAAM,WAAW,qBAAqB;EAGtC,MAAM,QAAQ,eAAe;GAC3B,MAAM,EAAE,OAAO,OAAO,UAAU,MAAM;GACtC,QAAQ,QAAQ,SAAS,QAAQ,KAAK,OAAO,KAAK,CAAC,IAAI,UAAU;EACnE,CAAC;EACD,MAAM,QAAQ,eACZ,MAAM,MAAM,QAAQ,SAAS,QAAQ,KAAK,OAAO,MAAM,MAAM,KAAK,CAAC,IAAI,KAAA,CACzE;EACA,MAAM,YAAY,eAAe;GAC/B,IAAI,MAAM,UAAU,KAAA,GAAW,OAAO;GACtC,MAAM,UAAU,GAAG,MAAM,QAAQ,IAAI,MAAM,MAAM,MAAM,QAAQ,IAAA,CAAK,QAAQ,CAAC,EAAE;GAC/E,OAAO,OAAO,SAAS,MAAM,WAAW,EAAE,OAAO,QAAQ,CAAC;EAC5D,CAAC;EACD,MAAM,SAAS,eAAe;GAC5B,MAAM,OAAO,MAAM,MAAM,QAAQ,QAAQ,KAAK,OAAO,MAAM,MAAM,KAAK,IAAI,KAAA;GAC1E,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,QAAQ,CAAC,CAAC,QAAQ,MAAmB,MAAM,KAAA,CAAS,IAAI,CAAC;EACjG,CAAC;;EAED,MAAM,cAAc,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC;;GAIhF,OAAAA,UAAA,GAAAC,mBAmBM,OAnBN,YAmBM,CAlBJC,YAQeC,MAAA,YAAA,GAAA;IAPZ,OAAO,MAAA;IACP,WAAW,MAAA,MAAM;IACjB,QAAQ,MAAA,MAAM;IACd,QAAQ,MAAA,MAAM;IACd,OAAO,MAAA,UAAU,KAAA,KAAa,MAAA,UAAK,IAAS,KAAA,IAAY,MAAA,QAAK,IAAA,OAAA;G,0BAE9C,UAAA,Q;IAAY,MAAA;IAAO,IAAAE,cAAe,CAAZC,gBAAAC,gBAAA,UAAA,KAAS,GAAA,CAAA,C;;;;;;;;G,IAEtC,OAAA,MAAO,SAAM,KAAQ,YAAA,SAAW,MAA3CP,UAAA,GAAAC,mBAQM,OARN,YAQM,CAPJC,YAMEC,MAAA,YAAA,GAAA;IALC,MAAM,OAAA;IACP,MAAK;IACL,QAAA;IACC,OAAOA,MAAA,IAAA,CAAI,CAAC,MAAM,QAAK;IACvB,QAAQ,YAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"table-settings.js","names":["_sfc_main"],"sources":["../../src/widgets/table-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouCheckbox, DouInput } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport SettingsField from './settings-field.vue'\nimport { fieldsOf, rowsOf } from './shared'\nimport SourceField from './source-field.vue'\nimport type { TableWidgetColumn, TableWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTableSettings' })\n\nconst model = defineModel<TableWidgetProps>({ required: true })\nconst messages = useDashboardMessages()\nconst { data } = useDashboardWidget()\n\n/** Every field of the rows, those shown first in their order. */\nconst fields = computed(() => {\n const all = fieldsOf(rowsOf(data.value, model.value.path))\n const shown = model.value.columns?.map((column) => column.key) ?? all\n return [...shown, ...all.filter((key) => !shown.includes(key))]\n})\nconst columns = computed<TableWidgetColumn[]>(\n () =>\n model.value.columns ?? fieldsOf(rowsOf(data.value, model.value.path)).map((key) => ({ key })),\n)\nconst columnOf = (key: string) => columns.value.find((column) => column.key === key)\n\nfunction toggle(key: string, on: boolean) {\n const next = on\n ? [...columns.value, { key }]\n : columns.value.filter((column) => column.key !== key)\n model.value = { ...model.value, columns: next }\n}\n\nfunction retitle(key: string, title: string) {\n const next = columns.value.map((column) =>\n column.key === key ? { key, ...(title ? { title } : {}) } : column,\n )\n model.value = { ...model.value, columns: next }\n}\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SourceField\n :model-value=\"model.source\"\n @update:model-value=\"(source) => (model = { ...model, source })\"\n />\n <SettingsField v-if=\"fields.length\" :label=\"messages.columns\">\n <div class=\"dou-dashboard__columns\">\n <div v-for=\"key in fields\" :key=\"key\" class=\"dou-dashboard__column\">\n <DouCheckbox\n :model-value=\"!!columnOf(key)\"\n @update:model-value=\"(on) => toggle(key, !!on)\"\n >\n {{ key }}\n </DouCheckbox>\n <DouInput\n v-if=\"columnOf(key)\"\n size=\"sm\"\n :model-value=\"columnOf(key)?.title ?? ''\"\n :placeholder=\"key\"\n :aria-label=\"format(messages.columnTitle, { field: key })\"\n @update:model-value=\"(title) => retitle(key, title)\"\n />\n </div>\n </div>\n </SettingsField>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"table-settings.js","names":["_sfc_main"],"sources":["../../src/widgets/table-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouCheckbox, DouInput } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport SettingsField from './settings-field.vue'\nimport { fieldsOf, rowsOf } from './shared'\nimport SourceField from './source-field.vue'\nimport type { TableWidgetColumn, TableWidgetProps } from './types'\nimport { tablePropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardTableSettings' })\n\nconst model = defineModel<TableWidgetProps>({ required: true })\n// the props as saved may have the wrong types: read them as the widget does\nconst view = computed(() => tablePropsOf(model.value as Record<string, unknown>))\nconst messages = useDashboardMessages()\nconst { data } = useDashboardWidget()\n\n/** Every field of the rows, those shown first in their order. */\nconst fields = computed(() => {\n const all = fieldsOf(rowsOf(data.value, view.value.path))\n const shown = view.value.columns?.map((column) => column.key) ?? all\n return [...shown, ...all.filter((key) => !shown.includes(key))]\n})\nconst columns = computed<TableWidgetColumn[]>(\n () => view.value.columns ?? fieldsOf(rowsOf(data.value, view.value.path)).map((key) => ({ key })),\n)\nconst columnOf = (key: string) => columns.value.find((column) => column.key === key)\n\nfunction toggle(key: string, on: boolean) {\n const next = on\n ? [...columns.value, { key }]\n : columns.value.filter((column) => column.key !== key)\n model.value = { ...model.value, columns: next }\n}\n\nfunction retitle(key: string, title: string) {\n const next = columns.value.map((column) =>\n column.key === key ? { key, ...(title ? { title } : {}) } : column,\n )\n model.value = { ...model.value, columns: next }\n}\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SourceField\n :model-value=\"view.source\"\n @update:model-value=\"(source) => (model = { ...model, source })\"\n />\n <SettingsField v-if=\"fields.length\" :label=\"messages.columns\">\n <div class=\"dou-dashboard__columns\">\n <div v-for=\"key in fields\" :key=\"key\" class=\"dou-dashboard__column\">\n <DouCheckbox\n :model-value=\"!!columnOf(key)\"\n @update:model-value=\"(on) => toggle(key, !!on)\"\n >\n {{ key }}\n </DouCheckbox>\n <DouInput\n v-if=\"columnOf(key)\"\n size=\"sm\"\n :model-value=\"columnOf(key)?.title ?? ''\"\n :placeholder=\"key\"\n :aria-label=\"format(messages.columnTitle, { field: key })\"\n @update:model-value=\"(title) => retitle(key, title)\"\n />\n </div>\n </div>\n </SettingsField>\n </div>\n</template>\n"],"mappings":""}
@@ -1,6 +1,7 @@
1
1
  import { format, useDashboardMessages } from "../locale.js";
2
2
  import { useDashboardWidget } from "../widget/context.js";
3
3
  import { fieldsOf, rowsOf } from "./shared.js";
4
+ import { tablePropsOf } from "./read-props.js";
4
5
  import settings_field_default from "./settings-field.js";
5
6
  import source_field_default from "./source-field.js";
6
7
  import { DouCheckbox, DouInput } from "dou-ui";
@@ -18,15 +19,16 @@ var table_settings_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
18
19
  emits: ["update:modelValue"],
19
20
  setup(__props) {
20
21
  const model = useModel(__props, "modelValue");
22
+ const view = computed(() => tablePropsOf(model.value));
21
23
  const messages = useDashboardMessages();
22
24
  const { data } = useDashboardWidget();
23
25
  /** Every field of the rows, those shown first in their order. */
24
26
  const fields = computed(() => {
25
- const all = fieldsOf(rowsOf(data.value, model.value.path));
26
- const shown = model.value.columns?.map((column) => column.key) ?? all;
27
+ const all = fieldsOf(rowsOf(data.value, view.value.path));
28
+ const shown = view.value.columns?.map((column) => column.key) ?? all;
27
29
  return [...shown, ...all.filter((key) => !shown.includes(key))];
28
30
  });
29
- const columns = computed(() => model.value.columns ?? fieldsOf(rowsOf(data.value, model.value.path)).map((key) => ({ key })));
31
+ const columns = computed(() => view.value.columns ?? fieldsOf(rowsOf(data.value, view.value.path)).map((key) => ({ key })));
30
32
  const columnOf = (key) => columns.value.find((column) => column.key === key);
31
33
  function toggle(key, on) {
32
34
  const next = on ? [...columns.value, { key }] : columns.value.filter((column) => column.key !== key);
@@ -47,7 +49,7 @@ var table_settings_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
47
49
  }
48
50
  return (_ctx, _cache) => {
49
51
  return openBlock(), createElementBlock("div", _hoisted_1, [createVNode(source_field_default, {
50
- "model-value": model.value.source,
52
+ "model-value": view.value.source,
51
53
  "onUpdate:modelValue": _cache[0] || (_cache[0] = (source) => model.value = {
52
54
  ...model.value,
53
55
  source
@@ -1 +1 @@
1
- {"version":3,"file":"table-settings.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","SourceField","_createBlock","SettingsField","_unref","_withCtx","_createElementVNode","_Fragment","_renderList","_createTextVNode","_toDisplayString","_createCommentVNode"],"sources":["../../src/widgets/table-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouCheckbox, DouInput } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport SettingsField from './settings-field.vue'\nimport { fieldsOf, rowsOf } from './shared'\nimport SourceField from './source-field.vue'\nimport type { TableWidgetColumn, TableWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTableSettings' })\n\nconst model = defineModel<TableWidgetProps>({ required: true })\nconst messages = useDashboardMessages()\nconst { data } = useDashboardWidget()\n\n/** Every field of the rows, those shown first in their order. */\nconst fields = computed(() => {\n const all = fieldsOf(rowsOf(data.value, model.value.path))\n const shown = model.value.columns?.map((column) => column.key) ?? all\n return [...shown, ...all.filter((key) => !shown.includes(key))]\n})\nconst columns = computed<TableWidgetColumn[]>(\n () =>\n model.value.columns ?? fieldsOf(rowsOf(data.value, model.value.path)).map((key) => ({ key })),\n)\nconst columnOf = (key: string) => columns.value.find((column) => column.key === key)\n\nfunction toggle(key: string, on: boolean) {\n const next = on\n ? [...columns.value, { key }]\n : columns.value.filter((column) => column.key !== key)\n model.value = { ...model.value, columns: next }\n}\n\nfunction retitle(key: string, title: string) {\n const next = columns.value.map((column) =>\n column.key === key ? { key, ...(title ? { title } : {}) } : column,\n )\n model.value = { ...model.value, columns: next }\n}\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SourceField\n :model-value=\"model.source\"\n @update:model-value=\"(source) => (model = { ...model, source })\"\n />\n <SettingsField v-if=\"fields.length\" :label=\"messages.columns\">\n <div class=\"dou-dashboard__columns\">\n <div v-for=\"key in fields\" :key=\"key\" class=\"dou-dashboard__column\">\n <DouCheckbox\n :model-value=\"!!columnOf(key)\"\n @update:model-value=\"(on) => toggle(key, !!on)\"\n >\n {{ key }}\n </DouCheckbox>\n <DouInput\n v-if=\"columnOf(key)\"\n size=\"sm\"\n :model-value=\"columnOf(key)?.title ?? ''\"\n :placeholder=\"key\"\n :aria-label=\"format(messages.columnTitle, { field: key })\"\n @update:model-value=\"(title) => retitle(key, title)\"\n />\n </div>\n </div>\n </SettingsField>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAYA,MAAM,QAAQA,SAA6B,SAAA,YAAmB;EAC9D,MAAM,WAAW,qBAAqB;EACtC,MAAM,EAAE,SAAS,mBAAmB;;EAGpC,MAAM,SAAS,eAAe;GAC5B,MAAM,MAAM,SAAS,OAAO,KAAK,OAAO,MAAM,MAAM,IAAI,CAAC;GACzD,MAAM,QAAQ,MAAM,MAAM,SAAS,KAAK,WAAW,OAAO,GAAG,KAAK;GAClE,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,QAAQ,QAAQ,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;EAChE,CAAC;EACD,MAAM,UAAU,eAEZ,MAAM,MAAM,WAAW,SAAS,OAAO,KAAK,OAAO,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,IAAI,EAAE,CAChG;EACA,MAAM,YAAY,QAAgB,QAAQ,MAAM,MAAM,WAAW,OAAO,QAAQ,GAAG;EAEnF,SAAS,OAAO,KAAa,IAAa;GACxC,MAAM,OAAO,KACT,CAAC,GAAG,QAAQ,OAAO,EAAE,IAAI,CAAC,IAC1B,QAAQ,MAAM,QAAQ,WAAW,OAAO,QAAQ,GAAG;GACvD,MAAM,QAAQ;IAAE,GAAG,MAAM;IAAO,SAAS;GAAK;EAChD;EAEA,SAAS,QAAQ,KAAa,OAAe;GAC3C,MAAM,OAAO,QAAQ,MAAM,KAAK,WAC9B,OAAO,QAAQ,MAAM;IAAE;IAAK,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GAAG,IAAI,MAC9D;GACA,MAAM,QAAQ;IAAE,GAAG,MAAM;IAAO,SAAS;GAAK;EAChD;;GAIE,OAAAC,UAAA,GAAAC,mBAyBM,OAzBN,YAyBM,CAxBJC,YAGEC,sBAAA;IAFC,eAAa,MAAA,MAAM;IACnB,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAY,MAAA,QAAK;KAAA,GAAQ,MAAA;KAAO;IAAM;G,8BAEzC,OAAA,MAAO,UAA5BH,UAAA,GAAAI,YAmBgBC,wBAAA;;IAnBqB,OAAOC,MAAA,QAAA,CAAQ,CAAC;;IACnD,SAAAC,cAiBM,CAjBNC,mBAiBM,OAjBN,YAiBM,EAhBJR,UAAA,IAAA,GAAAC,mBAeMQ,UAAA,MAAAC,WAfa,OAAA,QAAP,QAAG;KAAf,OAAAV,UAAA,GAAAC,mBAeM,OAAA;MAf2B;MAAK,OAAM;K,IAC1CC,YAKcI,MAAA,WAAA,GAAA;MAJX,eAAW,CAAA,CAAI,SAAS,GAAG;MAC3B,wBAAqB,OAAO,OAAO,KAAG,CAAA,CAAI,EAAE;;MAE7C,SAAAC,cAAS,CAANI,gBAAAC,gBAAA,GAAG,GAAA,CAAA,C;;K,kDAGA,SAAS,GAAG,KADpBZ,UAAA,GAAAI,YAOEE,MAAA,QAAA,GAAA;;MALA,MAAK;MACJ,eAAa,SAAS,GAAG,CAAA,EAAG,SAAK;MACjC,aAAa;MACb,cAAYA,MAAA,MAAA,CAAM,CAACA,MAAA,QAAA,CAAQ,CAAC,aAAW,EAAA,OAAW,IAAG,CAAA;MACrD,wBAAqB,UAAU,QAAQ,KAAK,KAAK"}
1
+ {"version":3,"file":"table-settings.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","SourceField","_createBlock","SettingsField","_unref","_withCtx","_createElementVNode","_Fragment","_renderList","_createTextVNode","_toDisplayString","_createCommentVNode"],"sources":["../../src/widgets/table-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouCheckbox, DouInput } from 'dou-ui'\nimport { computed } from 'vue'\nimport { format, useDashboardMessages } from '../locale'\nimport { useDashboardWidget } from '../widget/context'\nimport SettingsField from './settings-field.vue'\nimport { fieldsOf, rowsOf } from './shared'\nimport SourceField from './source-field.vue'\nimport type { TableWidgetColumn, TableWidgetProps } from './types'\nimport { tablePropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardTableSettings' })\n\nconst model = defineModel<TableWidgetProps>({ required: true })\n// the props as saved may have the wrong types: read them as the widget does\nconst view = computed(() => tablePropsOf(model.value as Record<string, unknown>))\nconst messages = useDashboardMessages()\nconst { data } = useDashboardWidget()\n\n/** Every field of the rows, those shown first in their order. */\nconst fields = computed(() => {\n const all = fieldsOf(rowsOf(data.value, view.value.path))\n const shown = view.value.columns?.map((column) => column.key) ?? all\n return [...shown, ...all.filter((key) => !shown.includes(key))]\n})\nconst columns = computed<TableWidgetColumn[]>(\n () => view.value.columns ?? fieldsOf(rowsOf(data.value, view.value.path)).map((key) => ({ key })),\n)\nconst columnOf = (key: string) => columns.value.find((column) => column.key === key)\n\nfunction toggle(key: string, on: boolean) {\n const next = on\n ? [...columns.value, { key }]\n : columns.value.filter((column) => column.key !== key)\n model.value = { ...model.value, columns: next }\n}\n\nfunction retitle(key: string, title: string) {\n const next = columns.value.map((column) =>\n column.key === key ? { key, ...(title ? { title } : {}) } : column,\n )\n model.value = { ...model.value, columns: next }\n}\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SourceField\n :model-value=\"view.source\"\n @update:model-value=\"(source) => (model = { ...model, source })\"\n />\n <SettingsField v-if=\"fields.length\" :label=\"messages.columns\">\n <div class=\"dou-dashboard__columns\">\n <div v-for=\"key in fields\" :key=\"key\" class=\"dou-dashboard__column\">\n <DouCheckbox\n :model-value=\"!!columnOf(key)\"\n @update:model-value=\"(on) => toggle(key, !!on)\"\n >\n {{ key }}\n </DouCheckbox>\n <DouInput\n v-if=\"columnOf(key)\"\n size=\"sm\"\n :model-value=\"columnOf(key)?.title ?? ''\"\n :placeholder=\"key\"\n :aria-label=\"format(messages.columnTitle, { field: key })\"\n @update:model-value=\"(title) => retitle(key, title)\"\n />\n </div>\n </div>\n </SettingsField>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAaA,MAAM,QAAQA,SAA6B,SAAA,YAAmB;EAE9D,MAAM,OAAO,eAAe,aAAa,MAAM,KAAgC,CAAC;EAChF,MAAM,WAAW,qBAAqB;EACtC,MAAM,EAAE,SAAS,mBAAmB;;EAGpC,MAAM,SAAS,eAAe;GAC5B,MAAM,MAAM,SAAS,OAAO,KAAK,OAAO,KAAK,MAAM,IAAI,CAAC;GACxD,MAAM,QAAQ,KAAK,MAAM,SAAS,KAAK,WAAW,OAAO,GAAG,KAAK;GACjE,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,QAAQ,QAAQ,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;EAChE,CAAC;EACD,MAAM,UAAU,eACR,KAAK,MAAM,WAAW,SAAS,OAAO,KAAK,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,IAAI,EAAE,CAClG;EACA,MAAM,YAAY,QAAgB,QAAQ,MAAM,MAAM,WAAW,OAAO,QAAQ,GAAG;EAEnF,SAAS,OAAO,KAAa,IAAa;GACxC,MAAM,OAAO,KACT,CAAC,GAAG,QAAQ,OAAO,EAAE,IAAI,CAAC,IAC1B,QAAQ,MAAM,QAAQ,WAAW,OAAO,QAAQ,GAAG;GACvD,MAAM,QAAQ;IAAE,GAAG,MAAM;IAAO,SAAS;GAAK;EAChD;EAEA,SAAS,QAAQ,KAAa,OAAe;GAC3C,MAAM,OAAO,QAAQ,MAAM,KAAK,WAC9B,OAAO,QAAQ,MAAM;IAAE;IAAK,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GAAG,IAAI,MAC9D;GACA,MAAM,QAAQ;IAAE,GAAG,MAAM;IAAO,SAAS;GAAK;EAChD;;GAIE,OAAAC,UAAA,GAAAC,mBAyBM,OAzBN,YAyBM,CAxBJC,YAGEC,sBAAA;IAFC,eAAa,KAAA,MAAK;IAClB,uBAAkB,OAAA,OAAA,OAAA,MAAG,WAAY,MAAA,QAAK;KAAA,GAAQ,MAAA;KAAO;IAAM;G,8BAEzC,OAAA,MAAO,UAA5BH,UAAA,GAAAI,YAmBgBC,wBAAA;;IAnBqB,OAAOC,MAAA,QAAA,CAAQ,CAAC;;IACnD,SAAAC,cAiBM,CAjBNC,mBAiBM,OAjBN,YAiBM,EAhBJR,UAAA,IAAA,GAAAC,mBAeMQ,UAAA,MAAAC,WAfa,OAAA,QAAP,QAAG;KAAf,OAAAV,UAAA,GAAAC,mBAeM,OAAA;MAf2B;MAAK,OAAM;K,IAC1CC,YAKcI,MAAA,WAAA,GAAA;MAJX,eAAW,CAAA,CAAI,SAAS,GAAG;MAC3B,wBAAqB,OAAO,OAAO,KAAG,CAAA,CAAI,EAAE;;MAE7C,SAAAC,cAAS,CAANI,gBAAAC,gBAAA,GAAG,GAAA,CAAA,C;;K,kDAGA,SAAS,GAAG,KADpBZ,UAAA,GAAAI,YAOEE,MAAA,QAAA,GAAA;;MALA,MAAK;MACJ,eAAa,SAAS,GAAG,CAAA,EAAG,SAAK;MACjC,aAAa;MACb,cAAYA,MAAA,MAAA,CAAM,CAACA,MAAA,QAAA,CAAQ,CAAC,aAAW,EAAA,OAAW,IAAG,CAAA;MACrD,wBAAqB,UAAU,QAAQ,KAAK,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","names":["_sfc_main"],"sources":["../../src/widgets/table.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouTable } from 'dou-ui'\nimport type { TableColumn } from 'dou-ui'\nimport { computed, onMounted, ref } from 'vue'\nimport { useDashboardWidget } from '../widget/context'\nimport { fieldsOf, rowsToWorkbook, rowsOf } from './shared'\nimport type { TableWidgetColumn, TableWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTableWidget' })\n\nconst { props, data, size, setWorkbook } = useDashboardWidget<TableWidgetProps>()\nconst rows = computed(() => rowsOf(data.value, props.value.path))\n/** Each row's key: its `rowKey` field, or its place in the list. */\nconst keys = computed(() => {\n const map = new WeakMap<object, string | number>()\n const field = props.value.rowKey\n rows.value.forEach((row, index) => map.set(row, field ? (row[field] as string | number) : index))\n return map\n})\nconst rowKey = (row: Record<string, unknown>) => keys.value.get(row) ?? ''\nconst number = new Intl.NumberFormat()\n/** The table's font, read once it is on the page, to measure texts with. */\nconst root = ref<{ $el: Element }>()\nconst font = ref('')\nonMounted(() => {\n const cell = root.value?.$el.querySelector('td, th')\n if (cell) font.value = getComputedStyle(cell).font\n})\nlet context: CanvasRenderingContext2D | null | undefined\n/** How wide a text is in the table's font, or about how wide before it is known. */\nfunction textWidth(text: string) {\n context ??=\n typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d')\n if (context && font.value) {\n context.font = font.value\n return context.measureText(text).width\n }\n let width = 0\n for (const char of text) width += char.charCodeAt(0) > 0x2e7f ? 14 : 8.5\n return width\n}\n/** Room for the title and the first rows' texts, with the cell's padding; up to 240px. */\nfunction minWidthOf(title: string, texts: unknown[]) {\n let widest = textWidth(title)\n for (const text of texts) widest = Math.max(widest, textWidth(String(text ?? '')))\n return Math.min(240, Math.ceil(widest) + 28)\n}\nconst columns = computed<TableColumn[]>(() => {\n const first = rows.value[0]\n const list: TableWidgetColumn[] =\n props.value.columns ?? fieldsOf(rows.value).map((key) => ({ key }))\n return list.map(({ key, title }) => {\n const numeric = typeof first?.[key] === 'number'\n // numbers with digit groups, as in the stat widget\n const value = numeric\n ? (row: Record<string, unknown>) =>\n typeof row[key] === 'number' ? number.format(row[key] as number) : row[key]\n : undefined\n const sample = rows.value.slice(0, 20).map((row) => (value ? value(row) : row[key]))\n const least = minWidthOf(title || key, sample)\n return {\n key,\n title: title || key,\n align: numeric ? 'end' : undefined,\n ellipsis: true,\n // shares of the width follow the contents; never narrower than them\n width: least,\n minWidth: least,\n value,\n }\n })\n})\n// the export menu writes the rows as they are, numbers without digit groups\nsetWorkbook(() =>\n rowsToWorkbook(\n '',\n columns.value.map((column) => ({\n key: column.key as string,\n title: String(column.title),\n width: typeof column.width === 'number' ? column.width : undefined,\n })),\n rows.value,\n ),\n)\n</script>\n\n<template>\n <DouTable\n ref=\"root\"\n class=\"dou-dashboard-table\"\n :bordered=\"false\"\n :data=\"rows\"\n :columns=\"columns\"\n :row-key=\"rowKey\"\n size=\"sm\"\n :max-height=\"size.height.value || undefined\"\n :virtual=\"rows.length > 100\"\n />\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"table.js","names":["_sfc_main"],"sources":["../../src/widgets/table.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouTable } from 'dou-ui'\nimport type { TableColumn } from 'dou-ui'\nimport { computed, onMounted, ref } from 'vue'\nimport { useDashboardWidget } from '../widget/context'\nimport { tablePropsOf } from './read-props'\nimport { fieldsOf, rowsToWorkbook, rowsOf } from './shared'\nimport type { TableWidgetColumn } from './types'\n\ndefineOptions({ name: 'DouDashboardTableWidget' })\n\nconst { props: raw, data, size, setWorkbook } = useDashboardWidget()\nconst props = computed(() => tablePropsOf(raw.value))\nconst rows = computed(() => rowsOf(data.value, props.value.path))\n/** Each row's key: its `rowKey` field, or its place in the list. */\nconst keys = computed(() => {\n const map = new WeakMap<object, string | number>()\n const field = props.value.rowKey\n rows.value.forEach((row, index) => map.set(row, field ? (row[field] as string | number) : index))\n return map\n})\nconst rowKey = (row: Record<string, unknown>) => keys.value.get(row) ?? ''\nconst number = new Intl.NumberFormat()\n/** The table's font, read once it is on the page, to measure texts with. */\nconst root = ref<{ $el: Element }>()\nconst font = ref('')\nonMounted(() => {\n const cell = root.value?.$el.querySelector('td, th')\n if (cell) font.value = getComputedStyle(cell).font\n})\nlet context: CanvasRenderingContext2D | null | undefined\n/** How wide a text is in the table's font, or about how wide before it is known. */\nfunction textWidth(text: string) {\n context ??=\n typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d')\n if (context && font.value) {\n context.font = font.value\n return context.measureText(text).width\n }\n let width = 0\n for (const char of text) width += char.charCodeAt(0) > 0x2e7f ? 14 : 8.5\n return width\n}\n/** Room for the title and the first rows' texts, with the cell's padding; up to 240px. */\nfunction minWidthOf(title: string, texts: unknown[]) {\n let widest = textWidth(title)\n for (const text of texts) widest = Math.max(widest, textWidth(String(text ?? '')))\n return Math.min(240, Math.ceil(widest) + 28)\n}\nconst columns = computed<TableColumn[]>(() => {\n const first = rows.value[0]\n const list: TableWidgetColumn[] =\n props.value.columns ?? fieldsOf(rows.value).map((key) => ({ key }))\n return list.map(({ key, title }) => {\n const numeric = typeof first?.[key] === 'number'\n // numbers with digit groups, as in the stat widget\n const value = numeric\n ? (row: Record<string, unknown>) =>\n typeof row[key] === 'number' ? number.format(row[key] as number) : row[key]\n : undefined\n const sample = rows.value.slice(0, 20).map((row) => (value ? value(row) : row[key]))\n const least = minWidthOf(title || key, sample)\n return {\n key,\n title: title || key,\n align: numeric ? 'end' : undefined,\n ellipsis: true,\n // shares of the width follow the contents; never narrower than them\n width: least,\n minWidth: least,\n value,\n }\n })\n})\n// the export menu writes the rows as they are, numbers without digit groups\nsetWorkbook(() =>\n rowsToWorkbook(\n '',\n columns.value.map((column) => ({\n key: column.key as string,\n title: String(column.title),\n width: typeof column.width === 'number' ? column.width : undefined,\n })),\n rows.value,\n ),\n)\n</script>\n\n<template>\n <DouTable\n ref=\"root\"\n class=\"dou-dashboard-table\"\n :bordered=\"false\"\n :data=\"rows\"\n :columns=\"columns\"\n :row-key=\"rowKey\"\n size=\"sm\"\n :max-height=\"size.height.value || undefined\"\n :virtual=\"rows.length > 100\"\n />\n</template>\n"],"mappings":""}
@@ -1,5 +1,6 @@
1
1
  import { useDashboardWidget } from "../widget/context.js";
2
2
  import { fieldsOf, rowsOf, rowsToWorkbook } from "./shared.js";
3
+ import { tablePropsOf } from "./read-props.js";
3
4
  import { DouTable } from "dou-ui";
4
5
  import { computed, createBlock, defineComponent, onMounted, openBlock, ref, unref } from "vue";
5
6
  // src/widgets/table.vue?vue&type=script&setup=true&lang.ts
@@ -7,7 +8,8 @@ var table_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
7
8
  name: "DouDashboardTableWidget",
8
9
  __name: "table",
9
10
  setup(__props) {
10
- const { props, data, size, setWorkbook } = useDashboardWidget();
11
+ const { props: raw, data, size, setWorkbook } = useDashboardWidget();
12
+ const props = computed(() => tablePropsOf(raw.value));
11
13
  const rows = computed(() => rowsOf(data.value, props.value.path));
12
14
  /** Each row's key: its `rowKey` field, or its place in the list. */
13
15
  const keys = computed(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"table.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref"],"sources":["../../src/widgets/table.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouTable } from 'dou-ui'\nimport type { TableColumn } from 'dou-ui'\nimport { computed, onMounted, ref } from 'vue'\nimport { useDashboardWidget } from '../widget/context'\nimport { fieldsOf, rowsToWorkbook, rowsOf } from './shared'\nimport type { TableWidgetColumn, TableWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTableWidget' })\n\nconst { props, data, size, setWorkbook } = useDashboardWidget<TableWidgetProps>()\nconst rows = computed(() => rowsOf(data.value, props.value.path))\n/** Each row's key: its `rowKey` field, or its place in the list. */\nconst keys = computed(() => {\n const map = new WeakMap<object, string | number>()\n const field = props.value.rowKey\n rows.value.forEach((row, index) => map.set(row, field ? (row[field] as string | number) : index))\n return map\n})\nconst rowKey = (row: Record<string, unknown>) => keys.value.get(row) ?? ''\nconst number = new Intl.NumberFormat()\n/** The table's font, read once it is on the page, to measure texts with. */\nconst root = ref<{ $el: Element }>()\nconst font = ref('')\nonMounted(() => {\n const cell = root.value?.$el.querySelector('td, th')\n if (cell) font.value = getComputedStyle(cell).font\n})\nlet context: CanvasRenderingContext2D | null | undefined\n/** How wide a text is in the table's font, or about how wide before it is known. */\nfunction textWidth(text: string) {\n context ??=\n typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d')\n if (context && font.value) {\n context.font = font.value\n return context.measureText(text).width\n }\n let width = 0\n for (const char of text) width += char.charCodeAt(0) > 0x2e7f ? 14 : 8.5\n return width\n}\n/** Room for the title and the first rows' texts, with the cell's padding; up to 240px. */\nfunction minWidthOf(title: string, texts: unknown[]) {\n let widest = textWidth(title)\n for (const text of texts) widest = Math.max(widest, textWidth(String(text ?? '')))\n return Math.min(240, Math.ceil(widest) + 28)\n}\nconst columns = computed<TableColumn[]>(() => {\n const first = rows.value[0]\n const list: TableWidgetColumn[] =\n props.value.columns ?? fieldsOf(rows.value).map((key) => ({ key }))\n return list.map(({ key, title }) => {\n const numeric = typeof first?.[key] === 'number'\n // numbers with digit groups, as in the stat widget\n const value = numeric\n ? (row: Record<string, unknown>) =>\n typeof row[key] === 'number' ? number.format(row[key] as number) : row[key]\n : undefined\n const sample = rows.value.slice(0, 20).map((row) => (value ? value(row) : row[key]))\n const least = minWidthOf(title || key, sample)\n return {\n key,\n title: title || key,\n align: numeric ? 'end' : undefined,\n ellipsis: true,\n // shares of the width follow the contents; never narrower than them\n width: least,\n minWidth: least,\n value,\n }\n })\n})\n// the export menu writes the rows as they are, numbers without digit groups\nsetWorkbook(() =>\n rowsToWorkbook(\n '',\n columns.value.map((column) => ({\n key: column.key as string,\n title: String(column.title),\n width: typeof column.width === 'number' ? column.width : undefined,\n })),\n rows.value,\n ),\n)\n</script>\n\n<template>\n <DouTable\n ref=\"root\"\n class=\"dou-dashboard-table\"\n :bordered=\"false\"\n :data=\"rows\"\n :columns=\"columns\"\n :row-key=\"rowKey\"\n size=\"sm\"\n :max-height=\"size.height.value || undefined\"\n :virtual=\"rows.length > 100\"\n />\n</template>\n"],"mappings":";;;;;;;;;EAUA,MAAM,EAAE,OAAO,MAAM,MAAM,gBAAgB,mBAAqC;EAChF,MAAM,OAAO,eAAe,OAAO,KAAK,OAAO,MAAM,MAAM,IAAI,CAAC;;EAEhE,MAAM,OAAO,eAAe;GAC1B,MAAM,sBAAM,IAAI,QAAiC;GACjD,MAAM,QAAQ,MAAM,MAAM;GAC1B,KAAK,MAAM,SAAS,KAAK,UAAU,IAAI,IAAI,KAAK,QAAS,IAAI,SAA6B,KAAK,CAAC;GAChG,OAAO;EACT,CAAC;EACD,MAAM,UAAU,QAAiC,KAAK,MAAM,IAAI,GAAG,KAAK;EACxE,MAAM,SAAS,IAAI,KAAK,aAAa;;EAErC,MAAM,OAAO,IAAsB;EACnC,MAAM,OAAO,IAAI,EAAE;EACnB,gBAAgB;GACd,MAAM,OAAO,KAAK,OAAO,IAAI,cAAc,QAAQ;GACnD,IAAI,MAAM,KAAK,QAAQ,iBAAiB,IAAI,CAAC,CAAC;EAChD,CAAC;EACD,IAAI;;EAEJ,SAAS,UAAU,MAAc;GAC/B,YACE,OAAO,aAAa,cAAc,OAAO,SAAS,cAAc,QAAQ,CAAC,CAAC,WAAW,IAAI;GAC3F,IAAI,WAAW,KAAK,OAAO;IACzB,QAAQ,OAAO,KAAK;IACpB,OAAO,QAAQ,YAAY,IAAI,CAAC,CAAC;GACnC;GACA,IAAI,QAAQ;GACZ,KAAK,MAAM,QAAQ,MAAM,SAAS,KAAK,WAAW,CAAC,IAAI,QAAS,KAAK;GACrE,OAAO;EACT;;EAEA,SAAS,WAAW,OAAe,OAAkB;GACnD,IAAI,SAAS,UAAU,KAAK;GAC5B,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,IAAI,QAAQ,UAAU,OAAO,QAAQ,EAAE,CAAC,CAAC;GACjF,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,IAAI,EAAE;EAC7C;EACA,MAAM,UAAU,eAA8B;GAC5C,MAAM,QAAQ,KAAK,MAAM;GAGzB,QADE,MAAM,MAAM,WAAW,SAAS,KAAK,KAAK,CAAC,CAAC,KAAK,SAAS,EAAE,IAAI,EAAE,EAAA,CACxD,KAAK,EAAE,KAAK,YAAY;IAClC,MAAM,UAAU,OAAO,QAAQ,SAAS;IAExC,MAAM,QAAQ,WACT,QACC,OAAO,IAAI,SAAS,WAAW,OAAO,OAAO,IAAI,IAAc,IAAI,IAAI,OACzE,KAAA;IACJ,MAAM,SAAS,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,QAAS,QAAQ,MAAM,GAAG,IAAI,IAAI,IAAK;IACnF,MAAM,QAAQ,WAAW,SAAS,KAAK,MAAM;IAC7C,OAAO;KACL;KACA,OAAO,SAAS;KAChB,OAAO,UAAU,QAAQ,KAAA;KACzB,UAAU;KAEV,OAAO;KACP,UAAU;KACV;IACF;GACF,CAAC;EACH,CAAC;EAED,kBACE,eACE,IACA,QAAQ,MAAM,KAAK,YAAY;GAC7B,KAAK,OAAO;GACZ,OAAO,OAAO,OAAO,KAAK;GAC1B,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ,KAAA;EAC3D,EAAE,GACF,KAAK,KACP,CACF;;GAIE,OAAAA,UAAA,GAAAC,YAUEC,MAAA,QAAA,GAAA;IATI,SAAA;IAAJ,KAAI;IACJ,OAAM;IACL,UAAU;IACV,MAAM,KAAA;IACN,SAAS,QAAA;IACT,WAAS;IACV,MAAK;IACJ,cAAYA,MAAA,IAAA,CAAI,CAAC,OAAO,SAAS,KAAA;IACjC,SAAS,KAAA,MAAK,SAAM"}
1
+ {"version":3,"file":"table.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref"],"sources":["../../src/widgets/table.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouTable } from 'dou-ui'\nimport type { TableColumn } from 'dou-ui'\nimport { computed, onMounted, ref } from 'vue'\nimport { useDashboardWidget } from '../widget/context'\nimport { tablePropsOf } from './read-props'\nimport { fieldsOf, rowsToWorkbook, rowsOf } from './shared'\nimport type { TableWidgetColumn } from './types'\n\ndefineOptions({ name: 'DouDashboardTableWidget' })\n\nconst { props: raw, data, size, setWorkbook } = useDashboardWidget()\nconst props = computed(() => tablePropsOf(raw.value))\nconst rows = computed(() => rowsOf(data.value, props.value.path))\n/** Each row's key: its `rowKey` field, or its place in the list. */\nconst keys = computed(() => {\n const map = new WeakMap<object, string | number>()\n const field = props.value.rowKey\n rows.value.forEach((row, index) => map.set(row, field ? (row[field] as string | number) : index))\n return map\n})\nconst rowKey = (row: Record<string, unknown>) => keys.value.get(row) ?? ''\nconst number = new Intl.NumberFormat()\n/** The table's font, read once it is on the page, to measure texts with. */\nconst root = ref<{ $el: Element }>()\nconst font = ref('')\nonMounted(() => {\n const cell = root.value?.$el.querySelector('td, th')\n if (cell) font.value = getComputedStyle(cell).font\n})\nlet context: CanvasRenderingContext2D | null | undefined\n/** How wide a text is in the table's font, or about how wide before it is known. */\nfunction textWidth(text: string) {\n context ??=\n typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d')\n if (context && font.value) {\n context.font = font.value\n return context.measureText(text).width\n }\n let width = 0\n for (const char of text) width += char.charCodeAt(0) > 0x2e7f ? 14 : 8.5\n return width\n}\n/** Room for the title and the first rows' texts, with the cell's padding; up to 240px. */\nfunction minWidthOf(title: string, texts: unknown[]) {\n let widest = textWidth(title)\n for (const text of texts) widest = Math.max(widest, textWidth(String(text ?? '')))\n return Math.min(240, Math.ceil(widest) + 28)\n}\nconst columns = computed<TableColumn[]>(() => {\n const first = rows.value[0]\n const list: TableWidgetColumn[] =\n props.value.columns ?? fieldsOf(rows.value).map((key) => ({ key }))\n return list.map(({ key, title }) => {\n const numeric = typeof first?.[key] === 'number'\n // numbers with digit groups, as in the stat widget\n const value = numeric\n ? (row: Record<string, unknown>) =>\n typeof row[key] === 'number' ? number.format(row[key] as number) : row[key]\n : undefined\n const sample = rows.value.slice(0, 20).map((row) => (value ? value(row) : row[key]))\n const least = minWidthOf(title || key, sample)\n return {\n key,\n title: title || key,\n align: numeric ? 'end' : undefined,\n ellipsis: true,\n // shares of the width follow the contents; never narrower than them\n width: least,\n minWidth: least,\n value,\n }\n })\n})\n// the export menu writes the rows as they are, numbers without digit groups\nsetWorkbook(() =>\n rowsToWorkbook(\n '',\n columns.value.map((column) => ({\n key: column.key as string,\n title: String(column.title),\n width: typeof column.width === 'number' ? column.width : undefined,\n })),\n rows.value,\n ),\n)\n</script>\n\n<template>\n <DouTable\n ref=\"root\"\n class=\"dou-dashboard-table\"\n :bordered=\"false\"\n :data=\"rows\"\n :columns=\"columns\"\n :row-key=\"rowKey\"\n size=\"sm\"\n :max-height=\"size.height.value || undefined\"\n :virtual=\"rows.length > 100\"\n />\n</template>\n"],"mappings":";;;;;;;;;;EAWA,MAAM,EAAE,OAAO,KAAK,MAAM,MAAM,gBAAgB,mBAAmB;EACnE,MAAM,QAAQ,eAAe,aAAa,IAAI,KAAK,CAAC;EACpD,MAAM,OAAO,eAAe,OAAO,KAAK,OAAO,MAAM,MAAM,IAAI,CAAC;;EAEhE,MAAM,OAAO,eAAe;GAC1B,MAAM,sBAAM,IAAI,QAAiC;GACjD,MAAM,QAAQ,MAAM,MAAM;GAC1B,KAAK,MAAM,SAAS,KAAK,UAAU,IAAI,IAAI,KAAK,QAAS,IAAI,SAA6B,KAAK,CAAC;GAChG,OAAO;EACT,CAAC;EACD,MAAM,UAAU,QAAiC,KAAK,MAAM,IAAI,GAAG,KAAK;EACxE,MAAM,SAAS,IAAI,KAAK,aAAa;;EAErC,MAAM,OAAO,IAAsB;EACnC,MAAM,OAAO,IAAI,EAAE;EACnB,gBAAgB;GACd,MAAM,OAAO,KAAK,OAAO,IAAI,cAAc,QAAQ;GACnD,IAAI,MAAM,KAAK,QAAQ,iBAAiB,IAAI,CAAC,CAAC;EAChD,CAAC;EACD,IAAI;;EAEJ,SAAS,UAAU,MAAc;GAC/B,YACE,OAAO,aAAa,cAAc,OAAO,SAAS,cAAc,QAAQ,CAAC,CAAC,WAAW,IAAI;GAC3F,IAAI,WAAW,KAAK,OAAO;IACzB,QAAQ,OAAO,KAAK;IACpB,OAAO,QAAQ,YAAY,IAAI,CAAC,CAAC;GACnC;GACA,IAAI,QAAQ;GACZ,KAAK,MAAM,QAAQ,MAAM,SAAS,KAAK,WAAW,CAAC,IAAI,QAAS,KAAK;GACrE,OAAO;EACT;;EAEA,SAAS,WAAW,OAAe,OAAkB;GACnD,IAAI,SAAS,UAAU,KAAK;GAC5B,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,IAAI,QAAQ,UAAU,OAAO,QAAQ,EAAE,CAAC,CAAC;GACjF,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,IAAI,EAAE;EAC7C;EACA,MAAM,UAAU,eAA8B;GAC5C,MAAM,QAAQ,KAAK,MAAM;GAGzB,QADE,MAAM,MAAM,WAAW,SAAS,KAAK,KAAK,CAAC,CAAC,KAAK,SAAS,EAAE,IAAI,EAAE,EAAA,CACxD,KAAK,EAAE,KAAK,YAAY;IAClC,MAAM,UAAU,OAAO,QAAQ,SAAS;IAExC,MAAM,QAAQ,WACT,QACC,OAAO,IAAI,SAAS,WAAW,OAAO,OAAO,IAAI,IAAc,IAAI,IAAI,OACzE,KAAA;IACJ,MAAM,SAAS,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,QAAS,QAAQ,MAAM,GAAG,IAAI,IAAI,IAAK;IACnF,MAAM,QAAQ,WAAW,SAAS,KAAK,MAAM;IAC7C,OAAO;KACL;KACA,OAAO,SAAS;KAChB,OAAO,UAAU,QAAQ,KAAA;KACzB,UAAU;KAEV,OAAO;KACP,UAAU;KACV;IACF;GACF,CAAC;EACH,CAAC;EAED,kBACE,eACE,IACA,QAAQ,MAAM,KAAK,YAAY;GAC7B,KAAK,OAAO;GACZ,OAAO,OAAO,OAAO,KAAK;GAC1B,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ,KAAA;EAC3D,EAAE,GACF,KAAK,KACP,CACF;;GAIE,OAAAA,UAAA,GAAAC,YAUEC,MAAA,QAAA,GAAA;IATI,SAAA;IAAJ,KAAI;IACJ,OAAM;IACL,UAAU;IACV,MAAM,KAAA;IACN,SAAS,QAAA;IACT,WAAS;IACV,MAAK;IACJ,cAAYA,MAAA,IAAA,CAAI,CAAC,OAAO,SAAS,KAAA;IACjC,SAAS,KAAA,MAAK,SAAM"}
@@ -1 +1 @@
1
- {"version":3,"file":"text-settings.js","names":["_sfc_main"],"sources":["../../src/widgets/text-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSegmentedControl, DouTextarea } from 'dou-ui'\nimport { useDashboardMessages } from '../locale'\nimport SettingsField from './settings-field.vue'\nimport type { TextWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTextSettings' })\n\nconst model = defineModel<TextWidgetProps>({ required: true })\nconst messages = useDashboardMessages()\nconst set = (patch: Partial<TextWidgetProps>) => (model.value = { ...model.value, ...patch })\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SettingsField :label=\"messages.text\">\n <DouTextarea\n :model-value=\"model.text ?? ''\"\n autosize\n :rows=\"4\"\n :aria-label=\"messages.text\"\n @update:model-value=\"(text) => set({ text })\"\n />\n </SettingsField>\n <SettingsField :label=\"messages.textSize\">\n <DouSegmentedControl\n :model-value=\"model.size ?? 'md'\"\n :options=\"[\n { value: 'sm', label: messages.sizeSmall },\n { value: 'md', label: messages.sizeMedium },\n { value: 'lg', label: messages.sizeLarge },\n ]\"\n :aria-label=\"messages.textSize\"\n @update:model-value=\"(size) => set({ size: size as TextWidgetProps['size'] })\"\n />\n </SettingsField>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"text-settings.js","names":["_sfc_main"],"sources":["../../src/widgets/text-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { DouSegmentedControl, DouTextarea } from 'dou-ui'\nimport { useDashboardMessages } from '../locale'\nimport SettingsField from './settings-field.vue'\nimport type { TextWidgetProps } from './types'\nimport { textPropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardTextSettings' })\n\nconst model = defineModel<TextWidgetProps>({ required: true })\n// the props as saved may have the wrong types: read them as the widget does\nconst view = computed(() => textPropsOf(model.value as Record<string, unknown>))\nconst messages = useDashboardMessages()\nconst set = (patch: Partial<TextWidgetProps>) => (model.value = { ...model.value, ...patch })\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SettingsField :label=\"messages.text\">\n <DouTextarea\n :model-value=\"view.text ?? ''\"\n autosize\n :rows=\"4\"\n :aria-label=\"messages.text\"\n @update:model-value=\"(text) => set({ text })\"\n />\n </SettingsField>\n <SettingsField :label=\"messages.textSize\">\n <DouSegmentedControl\n :model-value=\"view.size ?? 'md'\"\n :options=\"[\n { value: 'sm', label: messages.sizeSmall },\n { value: 'md', label: messages.sizeMedium },\n { value: 'lg', label: messages.sizeLarge },\n ]\"\n :aria-label=\"messages.textSize\"\n @update:model-value=\"(size) => set({ size: size as TextWidgetProps['size'] })\"\n />\n </SettingsField>\n </div>\n</template>\n"],"mappings":""}
@@ -1,7 +1,8 @@
1
1
  import { useDashboardMessages } from "../locale.js";
2
+ import { textPropsOf } from "./read-props.js";
2
3
  import settings_field_default from "./settings-field.js";
3
4
  import { DouSegmentedControl, DouTextarea } from "dou-ui";
4
- import { createElementBlock, createVNode, defineComponent, openBlock, unref, useModel, withCtx } from "vue";
5
+ import { computed, createElementBlock, createVNode, defineComponent, openBlock, unref, useModel, withCtx } from "vue";
5
6
  // src/widgets/text-settings.vue?vue&type=script&setup=true&lang.ts
6
7
  var _hoisted_1 = { class: "dou-dashboard__settings" };
7
8
  var text_settings_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
@@ -14,6 +15,7 @@ var text_settings_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
14
15
  emits: ["update:modelValue"],
15
16
  setup(__props) {
16
17
  const model = useModel(__props, "modelValue");
18
+ const view = computed(() => textPropsOf(model.value));
17
19
  const messages = useDashboardMessages();
18
20
  const set = (patch) => model.value = {
19
21
  ...model.value,
@@ -22,7 +24,7 @@ var text_settings_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
22
24
  return (_ctx, _cache) => {
23
25
  return openBlock(), createElementBlock("div", _hoisted_1, [createVNode(settings_field_default, { label: unref(messages).text }, {
24
26
  default: withCtx(() => [createVNode(unref(DouTextarea), {
25
- "model-value": model.value.text ?? "",
27
+ "model-value": view.value.text ?? "",
26
28
  autosize: "",
27
29
  rows: 4,
28
30
  "aria-label": unref(messages).text,
@@ -31,7 +33,7 @@ var text_settings_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
31
33
  _: 1
32
34
  }, 8, ["label"]), createVNode(settings_field_default, { label: unref(messages).textSize }, {
33
35
  default: withCtx(() => [createVNode(unref(DouSegmentedControl), {
34
- "model-value": model.value.size ?? "md",
36
+ "model-value": view.value.size ?? "md",
35
37
  options: [
36
38
  {
37
39
  value: "sm",
@@ -1 +1 @@
1
- {"version":3,"file":"text-settings.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","SettingsField","_unref","_withCtx"],"sources":["../../src/widgets/text-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DouSegmentedControl, DouTextarea } from 'dou-ui'\nimport { useDashboardMessages } from '../locale'\nimport SettingsField from './settings-field.vue'\nimport type { TextWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTextSettings' })\n\nconst model = defineModel<TextWidgetProps>({ required: true })\nconst messages = useDashboardMessages()\nconst set = (patch: Partial<TextWidgetProps>) => (model.value = { ...model.value, ...patch })\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SettingsField :label=\"messages.text\">\n <DouTextarea\n :model-value=\"model.text ?? ''\"\n autosize\n :rows=\"4\"\n :aria-label=\"messages.text\"\n @update:model-value=\"(text) => set({ text })\"\n />\n </SettingsField>\n <SettingsField :label=\"messages.textSize\">\n <DouSegmentedControl\n :model-value=\"model.size ?? 'md'\"\n :options=\"[\n { value: 'sm', label: messages.sizeSmall },\n { value: 'md', label: messages.sizeMedium },\n { value: 'lg', label: messages.sizeLarge },\n ]\"\n :aria-label=\"messages.textSize\"\n @update:model-value=\"(size) => set({ size: size as TextWidgetProps['size'] })\"\n />\n </SettingsField>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;EAQA,MAAM,QAAQA,SAA4B,SAAA,YAAmB;EAC7D,MAAM,WAAW,qBAAqB;EACtC,MAAM,OAAO,UAAqC,MAAM,QAAQ;GAAE,GAAG,MAAM;GAAO,GAAG;EAAM;;GAIzF,OAAAC,UAAA,GAAAC,mBAsBM,OAtBN,YAsBM,CArBJC,YAQgBC,wBAAA,EARA,OAAOC,MAAA,QAAA,CAAQ,CAAC,K;IAC9B,SAAAC,cAME,CANFH,YAMEE,MAAA,WAAA,GAAA;KALC,eAAa,MAAA,MAAM,QAAI;KACxB,UAAA;KACC,MAAM;KACN,cAAYA,MAAA,QAAA,CAAQ,CAAC;KACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,SAAS,IAAG,EAAG,KAAI,CAAA;;;G,kBAG7CF,YAWgBC,wBAAA,EAXA,OAAOC,MAAA,QAAA,CAAQ,CAAC,S;IAC9B,SAAAC,cASE,CATFH,YASEE,MAAA,mBAAA,GAAA;KARC,eAAa,MAAA,MAAM,QAAI;KACvB,SAAO;MAAoC;OAAA,OAAA;OAAA,OAAAA,MAAA,QAAA,CAAQ,CAAC;MAAS;MAAoC;OAAA,OAAA;OAAA,OAAAA,MAAA,QAAA,CAAQ,CAAC;MAAU;MAAoC;OAAA,OAAA;OAAA,OAAAA,MAAA,QAAA,CAAQ,CAAC;MAAS;;KAK1K,cAAYA,MAAA,QAAA,CAAQ,CAAC;KACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,SAAS,IAAG,EAAS,KAAI,CAAA"}
1
+ {"version":3,"file":"text-settings.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_createVNode","SettingsField","_unref","_withCtx"],"sources":["../../src/widgets/text-settings.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { DouSegmentedControl, DouTextarea } from 'dou-ui'\nimport { useDashboardMessages } from '../locale'\nimport SettingsField from './settings-field.vue'\nimport type { TextWidgetProps } from './types'\nimport { textPropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardTextSettings' })\n\nconst model = defineModel<TextWidgetProps>({ required: true })\n// the props as saved may have the wrong types: read them as the widget does\nconst view = computed(() => textPropsOf(model.value as Record<string, unknown>))\nconst messages = useDashboardMessages()\nconst set = (patch: Partial<TextWidgetProps>) => (model.value = { ...model.value, ...patch })\n</script>\n\n<template>\n <div class=\"dou-dashboard__settings\">\n <SettingsField :label=\"messages.text\">\n <DouTextarea\n :model-value=\"view.text ?? ''\"\n autosize\n :rows=\"4\"\n :aria-label=\"messages.text\"\n @update:model-value=\"(text) => set({ text })\"\n />\n </SettingsField>\n <SettingsField :label=\"messages.textSize\">\n <DouSegmentedControl\n :model-value=\"view.size ?? 'md'\"\n :options=\"[\n { value: 'sm', label: messages.sizeSmall },\n { value: 'md', label: messages.sizeMedium },\n { value: 'lg', label: messages.sizeLarge },\n ]\"\n :aria-label=\"messages.textSize\"\n @update:model-value=\"(size) => set({ size: size as TextWidgetProps['size'] })\"\n />\n </SettingsField>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAUA,MAAM,QAAQA,SAA4B,SAAA,YAAmB;EAE7D,MAAM,OAAO,eAAe,YAAY,MAAM,KAAgC,CAAC;EAC/E,MAAM,WAAW,qBAAqB;EACtC,MAAM,OAAO,UAAqC,MAAM,QAAQ;GAAE,GAAG,MAAM;GAAO,GAAG;EAAM;;GAIzF,OAAAC,UAAA,GAAAC,mBAsBM,OAtBN,YAsBM,CArBJC,YAQgBC,wBAAA,EARA,OAAOC,MAAA,QAAA,CAAQ,CAAC,K;IAC9B,SAAAC,cAME,CANFH,YAMEE,MAAA,WAAA,GAAA;KALC,eAAa,KAAA,MAAK,QAAI;KACvB,UAAA;KACC,MAAM;KACN,cAAYA,MAAA,QAAA,CAAQ,CAAC;KACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,SAAS,IAAG,EAAG,KAAI,CAAA;;;G,kBAG7CF,YAWgBC,wBAAA,EAXA,OAAOC,MAAA,QAAA,CAAQ,CAAC,S;IAC9B,SAAAC,cASE,CATFH,YASEE,MAAA,mBAAA,GAAA;KARC,eAAa,KAAA,MAAK,QAAI;KACtB,SAAO;MAAoC;OAAA,OAAA;OAAA,OAAAA,MAAA,QAAA,CAAQ,CAAC;MAAS;MAAoC;OAAA,OAAA;OAAA,OAAAA,MAAA,QAAA,CAAQ,CAAC;MAAU;MAAoC;OAAA,OAAA;OAAA,OAAAA,MAAA,QAAA,CAAQ,CAAC;MAAS;;KAK1K,cAAYA,MAAA,QAAA,CAAQ,CAAC;KACrB,uBAAkB,OAAA,OAAA,OAAA,MAAG,SAAS,IAAG,EAAS,KAAI,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":["_sfc_main"],"sources":["../../src/widgets/text.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useDashboardWidget } from '../widget/context'\nimport type { TextWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTextWidget' })\n\nconst { props } = useDashboardWidget<TextWidgetProps>()\n</script>\n\n<template>\n <div :class=\"['dou-dashboard-text', `is-${props.size ?? 'md'}`]\">{{ props.text }}</div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"text.js","names":["_sfc_main"],"sources":["../../src/widgets/text.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useDashboardWidget } from '../widget/context'\nimport { textPropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardTextWidget' })\n\nconst { props: raw } = useDashboardWidget()\nconst props = computed(() => textPropsOf(raw.value))\n</script>\n\n<template>\n <div :class=\"['dou-dashboard-text', `is-${props.size ?? 'md'}`]\">{{ props.text }}</div>\n</template>\n"],"mappings":""}
@@ -1,13 +1,15 @@
1
1
  import { useDashboardWidget } from "../widget/context.js";
2
- import { createElementBlock, defineComponent, normalizeClass, openBlock, toDisplayString, unref } from "vue";
2
+ import { textPropsOf } from "./read-props.js";
3
+ import { computed, createElementBlock, defineComponent, normalizeClass, openBlock, toDisplayString } from "vue";
3
4
  // src/widgets/text.vue?vue&type=script&setup=true&lang.ts
4
5
  var text_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
5
6
  name: "DouDashboardTextWidget",
6
7
  __name: "text",
7
8
  setup(__props) {
8
- const { props } = useDashboardWidget();
9
+ const { props: raw } = useDashboardWidget();
10
+ const props = computed(() => textPropsOf(raw.value));
9
11
  return (_ctx, _cache) => {
10
- return openBlock(), createElementBlock("div", { class: normalizeClass(["dou-dashboard-text", `is-${unref(props).size ?? "md"}`]) }, toDisplayString(unref(props).text), 3);
12
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["dou-dashboard-text", `is-${props.value.size ?? "md"}`]) }, toDisplayString(props.value.text), 3);
11
13
  };
12
14
  }
13
15
  });
@@ -1 +1 @@
1
- {"version":3,"file":"text.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_toDisplayString"],"sources":["../../src/widgets/text.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useDashboardWidget } from '../widget/context'\nimport type { TextWidgetProps } from './types'\n\ndefineOptions({ name: 'DouDashboardTextWidget' })\n\nconst { props } = useDashboardWidget<TextWidgetProps>()\n</script>\n\n<template>\n <div :class=\"['dou-dashboard-text', `is-${props.size ?? 'md'}`]\">{{ props.text }}</div>\n</template>\n"],"mappings":";;;;;;;EAMA,MAAM,EAAE,UAAU,mBAAoC;;GAIpD,OAAAA,UAAA,GAAAC,mBAAuF,OAAA,EAAjF,OAAKC,eAAA,CAAA,sBAAA,MAA+BC,MAAA,KAAA,CAAK,CAAC,QAAI,MAAA,CAAA,EAAgB,GAAAC,gBAAAD,MAAA,KAAA,CAAK,CAAC,IAAI,GAAA,CAAA"}
1
+ {"version":3,"file":"text.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_toDisplayString"],"sources":["../../src/widgets/text.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useDashboardWidget } from '../widget/context'\nimport { textPropsOf } from './read-props'\n\ndefineOptions({ name: 'DouDashboardTextWidget' })\n\nconst { props: raw } = useDashboardWidget()\nconst props = computed(() => textPropsOf(raw.value))\n</script>\n\n<template>\n <div :class=\"['dou-dashboard-text', `is-${props.size ?? 'md'}`]\">{{ props.text }}</div>\n</template>\n"],"mappings":";;;;;;;;EAOA,MAAM,EAAE,OAAO,QAAQ,mBAAmB;EAC1C,MAAM,QAAQ,eAAe,YAAY,IAAI,KAAK,CAAC;;GAIjD,OAAAA,UAAA,GAAAC,mBAAuF,OAAA,EAAjF,OAAKC,eAAA,CAAA,sBAAA,MAA+B,MAAA,MAAM,QAAI,MAAA,CAAA,EAAgB,GAAAC,gBAAA,MAAA,MAAM,IAAI,GAAA,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dou-ui/dashboard",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "0.1.0-alpha.5",
4
4
  "description": "DouUI 的仪表盘:可拖动、可缩放的网格布局与仪表盘设计器",
5
5
  "keywords": [
6
6
  "vue",
@@ -67,9 +67,9 @@
67
67
  "build": "vite build && vue-tsc -p tsconfig.build.json && bun scripts/build-style.ts"
68
68
  },
69
69
  "peerDependencies": {
70
- "@dou-ui/chart": "0.1.0-alpha.3",
71
- "@dou-ui/pivot": "0.1.0-alpha.3",
72
- "dou-ui": "0.1.0-alpha.3",
70
+ "@dou-ui/chart": "0.1.0-alpha.5",
71
+ "@dou-ui/pivot": "0.1.0-alpha.5",
72
+ "dou-ui": "0.1.0-alpha.5",
73
73
  "vue": "^3.5.0",
74
74
  "yjs": "^13.6.0"
75
75
  },
@@ -85,12 +85,12 @@
85
85
  }
86
86
  },
87
87
  "dependencies": {
88
- "@dou-ui/icons": "0.1.0-alpha.3",
89
- "@dou-ui/sheet": "0.1.0-alpha.3"
88
+ "@dou-ui/icons": "0.1.0-alpha.5",
89
+ "@dou-ui/sheet": "0.1.0-alpha.5"
90
90
  },
91
91
  "devDependencies": {
92
- "@dou-ui/chart": "0.1.0-alpha.3",
93
- "@dou-ui/pivot": "0.1.0-alpha.3",
92
+ "@dou-ui/chart": "0.1.0-alpha.5",
93
+ "@dou-ui/pivot": "0.1.0-alpha.5",
94
94
  "y-protocols": "^1.0.7",
95
95
  "yjs": "^13.6.33"
96
96
  },