Browse Source

1、w-form-group支持自定义布局

2、w-textarea等基础组件支持插槽
3、w-grid的按钮响应式问题修复
4、w-grid的td-content支持任意类型
main
likunming 4 weeks ago
parent
commit
7b97258b3f
  1. 2
      io.sc.platform.core.frontend/package.json
  2. 17
      io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckbox.vue
  3. 10
      io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckboxGroup.vue
  4. 23
      io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue
  5. 10
      io.sc.platform.core.frontend/src/platform/components/color/WColorInput.vue
  6. 10
      io.sc.platform.core.frontend/src/platform/components/color/WColorInputPalette.vue
  7. 10
      io.sc.platform.core.frontend/src/platform/components/cron/WCron.vue
  8. 10
      io.sc.platform.core.frontend/src/platform/components/date/WDate.vue
  9. 10
      io.sc.platform.core.frontend/src/platform/components/date/WDateRange.vue
  10. 10
      io.sc.platform.core.frontend/src/platform/components/file/WFile.vue
  11. 2
      io.sc.platform.core.frontend/src/platform/components/form/FormElement.vue
  12. 92
      io.sc.platform.core.frontend/src/platform/components/form/FormField.ts
  13. 202
      io.sc.platform.core.frontend/src/platform/components/form/FormGroup.vue
  14. 18
      io.sc.platform.core.frontend/src/platform/components/form/ts/Constant.ts
  15. 2
      io.sc.platform.core.frontend/src/platform/components/form/ts/Form.ts
  16. 6
      io.sc.platform.core.frontend/src/platform/components/grid/TdContent.vue
  17. 9
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  18. 6
      io.sc.platform.core.frontend/src/platform/components/grid/extra/Editor.vue
  19. 2
      io.sc.platform.core.frontend/src/platform/components/grid/ts/function/RequestApi.ts
  20. 4
      io.sc.platform.core.frontend/src/platform/components/grid/ts/types/PropsType.ts
  21. 10
      io.sc.platform.core.frontend/src/platform/components/icon/WIcon.vue
  22. 10
      io.sc.platform.core.frontend/src/platform/components/number/WInteger.vue
  23. 10
      io.sc.platform.core.frontend/src/platform/components/number/WNumber.vue
  24. 10
      io.sc.platform.core.frontend/src/platform/components/password/WPassword.vue
  25. 10
      io.sc.platform.core.frontend/src/platform/components/position/WPosition.vue
  26. 10
      io.sc.platform.core.frontend/src/platform/components/radio/WRadio.vue
  27. 10
      io.sc.platform.core.frontend/src/platform/components/select/WGridSelect.vue
  28. 10
      io.sc.platform.core.frontend/src/platform/components/select/WInputSelect.vue
  29. 10
      io.sc.platform.core.frontend/src/platform/components/select/WOrgSelect.vue
  30. 10
      io.sc.platform.core.frontend/src/platform/components/select/WRoleSelect.vue
  31. 10
      io.sc.platform.core.frontend/src/platform/components/select/WSelect.vue
  32. 10
      io.sc.platform.core.frontend/src/platform/components/select/WUserSelect.vue
  33. 10
      io.sc.platform.core.frontend/src/platform/components/text/WText.vue
  34. 19
      io.sc.platform.core.frontend/src/platform/components/textarea/WTextarea.vue

2
io.sc.platform.core.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.2.60",
"version": "8.2.64",
"description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件",
"main": "dist/platform-core.js",

17
io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckbox.vue

@ -25,6 +25,10 @@
@update:model-value="fieldMethodsClass.updateValue"
></q-checkbox>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field>
</template>
<template v-else>
@ -35,18 +39,25 @@
:readonly="fieldMethodsClass.getReadOnly(props, modelValue)"
:disable="fieldMethodsClass.getDisable(props, modelValue)"
@update:model-value="fieldMethodsClass.updateValue"
></q-checkbox>
>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-checkbox>
</template>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const checkboxRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel({ type: Boolean, default: false });
interface FieldProps extends FormFieldProps {
@ -58,6 +69,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/checkbox/WCheckboxGroup.vue

@ -40,16 +40,22 @@
:disable="fieldMethodsClass.getDisable(props, modelValue)"
/>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const checkboxGroupRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<Array<string> | Array<number>>();
interface FieldProps extends FormFieldProps {
@ -71,6 +77,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
},
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

23
io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue

@ -20,26 +20,15 @@
</div>
<div ref="codemirrorContainerRef" :style="`width:100%; padding-top: ${lineNumber ? 4 : 2}px; overflow: auto;`"></div>
</template>
<template v-if="!Tools.isEmpty(modelValue) && attrs.button" #append>
<q-btn
round
dense
flat
v-bind="attrs.button"
:style="{
content: '',
position: 'absolute',
bottom: '5px',
right: '5px',
}"
@click.stop.prevent="buttonClick(attrs.button)"
/>
<template v-for="slotName in fieldMethods.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethods.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, onMounted, onUnmounted, watch } from 'vue';
import { ref, useAttrs, onMounted, onUnmounted, watch, useSlots } from 'vue';
import { Tools } from '@/platform';
import { EditorView } from '@codemirror/view';
import { EditorState, StateEffect, Compartment } from '@codemirror/state';
@ -62,10 +51,12 @@ import Toolbar from '@/platform/components/math/toolbar/Toolbar.vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const fieldRef = ref();
const codemirrorContainerRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
let editorView = null;
@ -127,6 +118,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_: any) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/color/WColorInput.vue

@ -51,17 +51,23 @@
@click="restoreDefaultValue"
></q-btn>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue';
import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const colorRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
const isShow = ref(false);
@ -76,6 +82,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
isShow.value = false;
if (props['onUpdateValue']) {

10
io.sc.platform.core.frontend/src/platform/components/color/WColorInputPalette.vue

@ -56,18 +56,24 @@
@click="restoreDefaultValue"
></q-btn>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue';
import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import { quasarColors } from './quasarColors';
import FormElementSlot from '../form/FormElementSlot.vue';
const colorRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
const isShow = ref(false);
@ -82,6 +88,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
modelValue.value = value_;
isShow.value = false;

10
io.sc.platform.core.frontend/src/platform/components/cron/WCron.vue

@ -55,11 +55,15 @@
</q-popup-proxy>
</q-btn>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { Tools } from '@/platform';
import SecondSegment from './w-cron-segment/SecondSegment.vue';
import MinuteSegment from './w-cron-segment/MinuteSegment.vue';
@ -70,9 +74,11 @@ import WeekSegment from './w-cron-segment/WeekSegment.vue';
import YearSegment from './w-cron-segment/YearSegment.vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const cronRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
const isShow = ref(false);
@ -91,6 +97,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/date/WDate.vue

@ -29,18 +29,24 @@
</q-popup-proxy>
</q-icon>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, watch } from 'vue';
import { ref, useAttrs, watch, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const dateRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {}
@ -48,6 +54,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/date/WDateRange.vue

@ -30,18 +30,24 @@
</q-popup-proxy>
</q-icon>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, computed } from 'vue';
import { ref, useAttrs, computed, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const dateRangeRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<object>();
interface FieldProps extends FormFieldProps {}
@ -49,6 +55,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/file/WFile.vue

@ -20,17 +20,23 @@
<template v-if="!fieldMethodsClass.getReadOnly(props, modelValue)" #append>
<q-icon name="attachment" />
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-file>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const fileRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<File | Array<File>>();
interface FieldProps extends FormFieldProps {
@ -41,6 +47,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
type: 'file',
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

2
io.sc.platform.core.frontend/src/platform/components/form/FormElement.vue

@ -1,6 +1,6 @@
<template>
<template v-if="field.type === Constant.GROUP_TYPE">
<FormGroup v-if="showFormGroupComputed" v-bind="field" :fields="field.fields" :style="form.getFieldStyle(field)"></FormGroup>
<FormGroup v-if="showFormGroupComputed" v-bind="field" :fields="field.fields" :component-style="form.getFieldStyle(field)"></FormGroup>
</template>
<template v-else>
<Field :field="props.field"></Field>

92
io.sc.platform.core.frontend/src/platform/components/form/FormField.ts

@ -9,22 +9,73 @@ export interface FormFieldProps {
readOnlyIf?: boolean | (() => void); // 是否只读
disableIf?: boolean | (() => void); // 是否禁用
rules?: Array<() => void>; // 验证规则集合
slot?: object; // 插槽集合
onUpdateValue?: () => void; // 值改变事件函数
}
export abstract class FormFieldMethods {
// 值改变事件
/**
*
*/
isTemplateSlot?: boolean;
/**
*
*/
slotNames?: string[];
/**
*
* @param value_
*/
abstract updateValue(value_): void;
// 验证方法
/**
*
*/
abstract validate(): Promise<boolean> | boolean;
// 设置值
/**
*
* @param value_
*/
abstract setValue(value_): void;
// 获取值
/**
*
*/
abstract getValue(): any;
// 清空值
/**
*
*/
abstract clearValue(): void;
// 获取验证规则集结果
/**
*
* @param slots
* @returns
*/
getSlotType(slots: any) {
return Object.keys(slots).length > 0;
}
/**
*
* @param slots
* @param props
*/
getSlotNames(slots: any, props: any) {
if (Object.keys(slots).length > 0) {
return Object.keys(slots);
} else if (props['slot']) {
return Object.keys(props['slot']);
}
return [];
}
/**
*
* @param props_
* @param value_
* @param componentRef_
* @param defaultValue_
* @returns
*/
getRules(props_, value_, componentRef_, defaultValue_) {
let result = props_.rules || <any>[];
if (!Tools.isEmpty(defaultValue_)) {
@ -42,8 +93,12 @@ export abstract class FormFieldMethods {
}
return result;
}
// 获取是否必填结果
/**
*
* @param props_
* @param value_
* @returns
*/
getRequired(props_, value_) {
if (!Tools.isEmpty(props_.requiredIf)) {
if (typeof props_.requiredIf === 'boolean') {
@ -54,7 +109,12 @@ export abstract class FormFieldMethods {
}
return false;
}
// 获取是否显示结果
/**
*
* @param props_
* @param value_
* @returns
*/
getShow(props_, value_) {
if (!Tools.isEmpty(props_.showIf)) {
if (typeof props_.showIf === 'boolean') {
@ -65,7 +125,12 @@ export abstract class FormFieldMethods {
}
return true;
}
// 获取是否只读结果
/**
*
* @param props_
* @param value_
* @returns
*/
getReadOnly(props_, value_) {
if (props_.form && props_.form.getStatus() === 'view') {
return true;
@ -79,7 +144,12 @@ export abstract class FormFieldMethods {
}
return false;
}
// 获取是否禁用结果
/**
*
* @param props_
* @param value_
* @returns
*/
getDisable(props_, value_) {
if (!Tools.isEmpty(props_.disableIf)) {
if (typeof props_.disableIf === 'boolean') {

202
io.sc.platform.core.frontend/src/platform/components/form/FormGroup.vue

@ -1,23 +1,34 @@
<template>
<div>
<q-card flat bordered>
<q-item dense style="padding: 0px">
<q-item-section>
<q-item-label header :style="headerStyleComputed">
<q-icon v-if="props.icon" :name="props.icon" size="sm" v-bind="props.iconAttrs" />
<span style="margin-left: 5px">{{ label }}</span>
</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-card-section style="padding: 8px">
<div class="grid" :style="layoutStyleComputed">
<template v-for="(field, index) in fields as any" :key="String(index)">
<FormElement :field="field"></FormElement>
</template>
<div :style="componentStyle">
<div v-if="cardModeComputed">
<q-card flat bordered>
<q-item dense style="padding: 0px">
<q-item-section>
<q-item-label header :style="cardModeHeaderStyleComputed">
<q-icon v-if="props.icon" :name="props.icon" size="sm" v-bind="props.iconAttrs" />
<span style="margin-left: 5px">{{ label }}</span>
</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-card-section style="padding: 8px">
<div :class="props.class" :style="contentStyleComputed">
<template v-for="(field, index) in fields as any" :key="String(index)">
<div :class="field.class" :style="formElementDivStyle(field)">
<FormElement :field="field"></FormElement>
</div>
</template>
</div>
</q-card-section>
</q-card>
</div>
<div v-else :class="props.class" :style="contentStyleComputed">
<template v-for="(field, index) in fields as any" :key="String(index)">
<div :class="field.class" :style="formElementDivStyle(field)">
<FormElement :field="field"></FormElement>
</div>
</q-card-section>
</q-card>
</template>
</div>
</div>
</template>
@ -26,6 +37,7 @@ import { inject, computed } from 'vue';
import { useQuasar } from 'quasar';
import { Tools } from '@/platform';
import { Form } from './ts/Form';
import { Constant } from './ts/Constant';
import FormElement from './FormElement.vue';
const $q = useQuasar();
@ -53,16 +65,35 @@ const colors = [red, orange, yellow, green, teal, blue, purple, grey];
const colorJson = { red, orange, yellow, green, teal, blue, purple, grey };
const props = defineProps({
//
//
mode: { type: String, default: Constant.FORM_GROUP_MODE.CONTAINER },
// card-
label: { type: String, default: '' },
//
color: { type: String, default: undefined },
//
// card-
headerBgColor: { type: String, default: undefined },
// card-
icon: { type: String, default: undefined },
//
// card-
iconAttrs: { type: Object, default: undefined },
// form
// div`class`carddivcontainerdiv
class: { type: String, default: undefined },
// divcarddivcontainerdiv
style: { type: String, default: undefined },
// divleftrightcenterbetweenform
//
// left = display: flex; justify-content: flex-start;
// right = display: flex; justify-content: flex-end;
// center = display: flex; justify-content: center;
// between = display: flex; justify-content: space-between;
// form = form ;
// classstylealigndivclassstylealignstyle
align: { type: String, default: undefined },
// `align` `form` form
colsNum: { type: [Number, Object], default: 0 },
// 使alignx
xGap: { type: Number, default: 8 },
// 使aligny
yGap: { type: Number, default: 4 },
//
fields: {
type: Array,
@ -70,9 +101,75 @@ const props = defineProps({
return [];
},
},
// ()
componentStyle: {
type: Object,
default: undefined,
},
});
/**
* 当前屏幕断点一列应该显示的元素个数
*/
const screenColsNumComputed = computed(() => {
if (typeof props.colsNum === 'number' && props.colsNum > 0) {
return props.colsNum;
} else if (typeof props.colsNum === 'object') {
const screen = { ...form.cm.screenCols, ...props.colsNum };
return screen[$q.screen.name];
}
return form.cm.screenCols[$q.screen.name];
});
/**
* 使用form布局时的样式
*/
const useFormLayoutStyleComputed = computed(() => {
const style = { display: 'grid' };
if (typeof props.colsNum === 'number' && props.colsNum > 0) {
style['grid-template-columns'] = 'repeat(' + props.colsNum + ', minmax(0, 1fr))';
} else {
style['grid-template-columns'] = 'repeat(' + screenColsNumComputed.value + ', minmax(0, 1fr))';
}
style['column-gap'] = form.props.xGap + 'px';
style['row-gap'] = form.props.yGap + 'px';
return style;
});
const headerStyleComputed = computed(() => {
const jsonStyle2String = (json: any) => {
return Object.entries(json)
.map(([k, v]) => `${k}:${v}`)
.join(';');
};
/**
* 快速布局对应的样式
*/
const alignJson = {
left: {
value: 'left',
style: 'display:flex; justify-content: flex-start;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
right: {
value: 'right',
style: 'display:flex; justify-content: flex-end;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
center: {
value: 'center',
style: 'display:flex; justify-content: center;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
between: {
value: 'between',
style: 'display:flex; justify-content: space-between;' + 'column-gap: ' + props.xGap + 'px;' + 'row-gap: ' + props.yGap + 'px;',
},
form: {
value: 'form',
style: jsonStyle2String(useFormLayoutStyleComputed.value),
},
};
/**
* card模式标题块样式
*/
const cardModeHeaderStyleComputed = computed(() => {
const style = {
//
display: 'flex',
@ -81,16 +178,16 @@ const headerStyleComputed = computed(() => {
color: '#000',
padding: '5px',
};
if (props.color) {
if (props.headerBgColor) {
//
if (props.color === 'auto') {
if (props.headerBgColor === 'auto') {
const index = form.fieldArray.value.findIndex((item) => item.label === props.label);
let colorIndex = index > -1 && index < colors.length ? index : getRandomInt();
style['background-color'] = colors[colorIndex];
} else if (Tools.hasOwnProperty(colorJson, props.color)) {
style['background-color'] = colorJson[props.color];
} else if (Tools.hasOwnProperty(colorJson, props.headerBgColor)) {
style['background-color'] = colorJson[props.headerBgColor];
} else {
style['background-color'] = props.color;
style['background-color'] = props.headerBgColor;
}
}
return style;
@ -103,25 +200,36 @@ const getRandomInt = () => {
return Math.floor(Math.random() * (max - min + 1) + min);
};
const screenColsNumComputed = computed(() => {
if (typeof props.colsNum === 'number' && props.colsNum > 0) {
return props.colsNum;
} else if (typeof props.colsNum === 'object') {
const screen = { ...form.cm.screenCols, ...props.colsNum };
return screen[$q.screen.name];
}
return form.cm.screenCols[$q.screen.name];
/**
* 当前为card模式
*/
const cardModeComputed = computed(() => {
return props.mode === Constant.FORM_GROUP_MODE.CARD;
});
const layoutStyleComputed = computed(() => {
const style = {};
if (typeof props.colsNum === 'number' && props.colsNum > 0) {
style['grid-template-columns'] = 'repeat(' + props.colsNum + ', minmax(0, 1fr))';
} else {
style['grid-template-columns'] = 'repeat(' + screenColsNumComputed.value + ', minmax(0, 1fr))';
/**
* 分组下内容块使用的样式
*/
const contentStyleComputed = computed(() => {
let styleStr = '';
if (props.style) {
//
styleStr = props.style + (props.style.trim().endsWith(';') ? '' : ';');
}
style['column-gap'] = form.props.xGap + 'px';
style['row-gap'] = form.props.yGap + 'px';
return style;
if (props.align && Tools.hasOwnProperty(alignJson, props.align)) {
styleStr += alignJson[props.align]['style'];
}
return styleStr;
});
const formElementDivStyle = (field: any) => {
let styleStr = '';
if (field.style) {
styleStr = field.style + (field.style.trim().endsWith(';') ? '' : ';');
}
if (props.align && props.align === alignJson.form.value) {
styleStr += jsonStyle2String(form.getFieldStyle(field));
}
return styleStr;
};
</script>

18
io.sc.platform.core.frontend/src/platform/components/form/ts/Constant.ts

@ -1,3 +1,14 @@
class FormGroupMode {
/**
* `icon` `label`
*/
static CARD = 'card';
/**
* `fields` `div`
*/
static CONTAINER = 'container';
}
/**
*
*/
@ -8,7 +19,12 @@ export class Constant {
static STATUS_ADD = 'add';
/**
*
*
*/
static GROUP_TYPE = 'w-form-group';
/**
* `w-form-group`
*/
static FORM_GROUP_MODE = FormGroupMode;
}

2
io.sc.platform.core.frontend/src/platform/components/form/ts/Form.ts

@ -102,7 +102,7 @@ export class Form {
} else {
if (field.colSpan === 'full') {
// col-span-${screenColsNumComputed.value}
style['grid-column'] = `span ${screenColsNum} / span ${screenColsNum}`;
style['grid-column'] = `1 / -1`;
} else {
if (field.colSpan && screenColsNum >= field.colSpan) {
// col-span-${field.colSpan}

6
io.sc.platform.core.frontend/src/platform/components/grid/TdContent.vue

@ -22,10 +22,8 @@ import { Constant, GridTools } from './ts/index';
const tools = <GridTools>inject('tools');
const props = defineProps({
value: {
type: [Object, String, Number],
default: () => {
return '';
},
type: null,
default: '',
},
col: {
type: Object,

9
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -108,6 +108,15 @@ watch(
},
);
// props
watch(
() => props.toolbarActions,
(newVal, oldVal) => {
tools.props = props;
getTopRef()?.handleToolbarActions();
},
);
eventBus.on('onLocaleChanged', (local) => {
nextTick(() => {
topRef.value?.handleQueryFormShowField();

6
io.sc.platform.core.frontend/src/platform/components/grid/extra/Editor.vue

@ -105,8 +105,6 @@ const addData = (dialogFormData) => {
} else {
tools.apiFM.localMode.addLocalData(dialogFormData, undefined);
}
//
tools.em.afterEditorDataSubmit({ grid: tools.instance, data: dialogFormData });
};
const updateData = (dialogFormData) => {
const selected = tools.apiFM.getData.getSelectedRow();
@ -121,8 +119,6 @@ const updateData = (dialogFormData) => {
dialogFormData['children'] = selected['children'];
}
tools.apiFM.localMode.updateLocalData(dialogFormData);
//
tools.em.afterEditorDataSubmit({ grid: tools.instance, data: dialogFormData });
};
const localModeSave = (dialogFormData: any, formStatus: string, closeDialog: boolean) => {
@ -132,6 +128,8 @@ const localModeSave = (dialogFormData: any, formStatus: string, closeDialog: boo
updateData(dialogFormData);
}
saveLoading.value = false;
//
tools.em.afterEditorDataSubmit(dialogFormData);
if (closeDialog) {
dialogRef.value.hide();
}

2
io.sc.platform.core.frontend/src/platform/components/grid/ts/function/RequestApi.ts

@ -130,7 +130,7 @@ export class RequestApi extends Base {
callback(resp);
}
NotifyManager.info($t('tip.operationSuccess') || '');
this.tools?.em.afterEditorDataSubmit({ grid: this.instance, data: resp.data });
this.tools?.em.afterEditorDataSubmit(resp.data);
})
.catch((error) => {
if (error?.code === 1001) {

4
io.sc.platform.core.frontend/src/platform/components/grid/ts/types/PropsType.ts

@ -58,7 +58,7 @@ export type PropsType = {
/**
* GETPOST使使
*/
customFetch: Function | undefined,
customFetch?: Function | undefined,
/**
*
*/
@ -170,7 +170,7 @@ export type PropsType = {
/**
* alone `format` 使format进行内容显示处理
*/
groupByTitle: string | Function,
groupByTitle?: string | Function,
/**
*
*/

10
io.sc.platform.core.frontend/src/platform/components/icon/WIcon.vue

@ -88,11 +88,15 @@
@click="restoreDefaultValue"
></q-btn>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue';
import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
@ -103,9 +107,11 @@ import eva from './icons/eva-icons.json';
import fontawesomeBrands from './icons/fontawesome-v6-icons-brands.json';
import fontawesomeRegular from './icons/fontawesome-v6-icons-regular.json';
import fontawesomeSolid from './icons/fontawesome-v6-icons-solid.json';
import FormElementSlot from '../form/FormElementSlot.vue';
const iconRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
const leftWidthRef = ref(30);
@ -123,6 +129,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/number/WInteger.vue

@ -16,22 +16,30 @@
@update:model-value="fieldMethodsClass.updateValue"
>
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { FormValidators } from '@/platform/components';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const numberRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<number>();
interface FieldProps extends FormFieldProps {}
const props = withDefaults(defineProps<FieldProps>(), { showIf: true }); // 使withDefaults
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
// FieldMethods
updateValue = (value_) => {
const floatValue = parseInt(value_);

10
io.sc.platform.core.frontend/src/platform/components/number/WNumber.vue

@ -16,18 +16,24 @@
@update:model-value="fieldMethodsClass.updateValue"
>
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, computed } from 'vue';
import { ref, useAttrs, computed, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormValidators } from '@/platform/components';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const numberRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<number>();
interface FieldProps extends FormFieldProps {
@ -36,6 +42,8 @@ interface FieldProps extends FormFieldProps {
}
const props = withDefaults(defineProps<FieldProps>(), { precision: undefined, showIf: true }); // 使withDefaults
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
// FieldMethods
updateValue = (value_) => {
const floatValue = parseFloat(value_);

10
io.sc.platform.core.frontend/src/platform/components/password/WPassword.vue

@ -16,17 +16,23 @@
@update:model-value="fieldMethodsClass.updateValue"
>
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const pwdRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {}
@ -34,6 +40,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/position/WPosition.vue

@ -57,17 +57,23 @@
@click="restoreDefaultValue"
></q-btn>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, toRaw, computed, useAttrs, onBeforeMount } from 'vue';
import { ref, toRaw, computed, useAttrs, onBeforeMount, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const positionRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
const positionList = ['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'];
@ -83,6 +89,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
restore: false,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
isShow.value = false;
modelValue.value = value_;

10
io.sc.platform.core.frontend/src/platform/components/radio/WRadio.vue

@ -59,17 +59,23 @@
@click.stop.prevent="fieldMethodsClass.clearValue"
></q-btn>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const radioRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | boolean | number>();
interface FieldProps extends FormFieldProps {
@ -93,6 +99,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
},
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WGridSelect.vue

@ -50,19 +50,25 @@
<template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-field>
</div>
</template>
<script setup lang="ts">
import { ref, computed, useAttrs, toRaw, watch, onMounted, nextTick } from 'vue';
import { ref, computed, useAttrs, toRaw, watch, onMounted, nextTick, useSlots } from 'vue';
import { Tools, axios } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref();
const gridRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>(); //
const modelDisplayValue = ref(''); //
const customDisplayValue = ref(''); // setDisplayValue
@ -103,6 +109,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
selectableIf: undefined,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
//
updateValue = (value_) => {
if (props['onUpdateValue']) {

10
io.sc.platform.core.frontend/src/platform/components/select/WInputSelect.vue

@ -35,18 +35,24 @@
<template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { onBeforeMount, ref, useAttrs, watch, useSlots } from 'vue';
import { Tools } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { onBeforeMount, ref, useAttrs, watch } from 'vue';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
const modelDisplayValue = ref(''); //
@ -61,6 +67,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
counter: false, //
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WOrgSelect.vue

@ -60,18 +60,24 @@
<template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount } from 'vue';
import { ref, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount, useSlots } from 'vue';
import { Tools, axios, Environment, Formater } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>();
const modelObjectValue = ref(<any>[]); //
const orgGridRef = ref();
@ -141,6 +147,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
queryCriteria: undefined,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WRoleSelect.vue

@ -74,18 +74,24 @@
<template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, computed, useAttrs, toRaw, watch, onMounted } from 'vue';
import { ref, computed, useAttrs, toRaw, watch, onMounted, useSlots } from 'vue';
import { Tools, axios, Environment, Formater } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>();
const modelObjectValue = ref(<any>[]); //
const roleGridRef = ref();
@ -123,6 +129,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
queryCriteria: undefined, // criteria
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WSelect.vue

@ -16,17 +16,23 @@
@update:model-value="fieldMethodsClass.updateValue"
>
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-select>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const selectRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | number | boolean | Array<string> | Array<number> | Array<boolean>>();
interface FieldProps extends FormFieldProps {}
@ -34,6 +40,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/select/WUserSelect.vue

@ -107,18 +107,24 @@
<template v-if="counter" #counter>
<div>{{ modelValue?.length }}</div>
</template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount } from 'vue';
import { ref, reactive, computed, useAttrs, toRaw, watch, onMounted, onBeforeMount, useSlots } from 'vue';
import { Tools, axios, Environment, Formater, $t, SessionManager } from '@/platform';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textSelectRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string | Array<string>>();
const modelObjectValue = ref(<any>[]); //
const userGridRef = ref();
@ -184,6 +190,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
roleQueryCriteria: undefined, //
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

10
io.sc.platform.core.frontend/src/platform/components/text/WText.vue

@ -15,16 +15,22 @@
@update:model-value="fieldMethodsClass.updateValue"
>
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, computed } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { ref, useAttrs, useSlots } from 'vue';
import { FormFieldMethods } from '../form/FormField';
import FormElementSlot from '../form/FormElementSlot.vue';
const textRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {}
@ -32,6 +38,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

19
io.sc.platform.core.frontend/src/platform/components/textarea/WTextarea.vue

@ -15,26 +15,23 @@
@update:model-value="fieldMethodsClass.updateValue"
>
<template #label><w-label :required="fieldMethodsClass.getRequired(props, modelValue)" :label="attrs.label"></w-label></template>
<template #default><slot></slot></template>
<template #prepend><slot name="prepend"></slot></template>
<template #append><slot name="append"></slot></template>
<template #before><slot name="before"></slot></template>
<template #after><slot name="after"></slot></template>
<template #error><slot name="error"></slot></template>
<template #hint><slot name="hint"></slot></template>
<template #counter><slot name="counter"></slot></template>
<template #loading><slot name="loading"></slot></template>
<template v-for="slotName in fieldMethodsClass.slotNames" :key="slotName" #[slotName]>
<slot v-if="fieldMethodsClass.isTemplateSlot" :name="slotName"></slot>
<FormElementSlot v-else :slot-name="slotName" :slot-content="props['slot'][slotName]"></FormElementSlot>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue';
import { FormFieldProps } from '@/platform/components/form/FormField.ts';
import { ref, useAttrs, useSlots } from 'vue';
import FormElementSlot from '../form/FormElementSlot.vue';
import { FormFieldMethods } from '../form/FormField';
const textareaRef = ref();
const attrs = useAttrs();
const slots = useSlots();
const modelValue = defineModel<string>();
interface FieldProps extends FormFieldProps {}
@ -42,6 +39,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
showIf: true,
});
class FieldMethods extends FormFieldMethods {
isTemplateSlot = this.getSlotType(slots);
slotNames = this.getSlotNames(slots, props);
updateValue = (value_) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({

Loading…
Cancel
Save