@@ -8,49 +8,61 @@ import { t } from "@app/locale"
88import { CircleCheck , Clock , Delete , EditPen , Lock } from "@element-plus/icons-vue"
99import { css } from '@emotion/css'
1010import Flex from "@pages/components/Flex"
11- import { ElButton , ElCard , ElCheckboxButton , ElCheckboxGroup , ElDivider , ElIcon , ElMessageBox , ElTag , useNamespace } from "element-plus"
12- import { createStringUnionGuard } from 'typescript-guard'
13- import { type Component , computed , defineComponent , FunctionalComponent , h , type StyleValue } from "vue"
14- import { verifyCanModify } from "../common"
15- import { useLimitAction , useLimitTable } from "../context"
11+ import {
12+ type CheckboxValueType , ElButton , ElCard , ElCheckboxButton , ElCheckboxGroup , ElDivider , ElIcon , ElMessageBox ,
13+ ElTag , type TagProps , useNamespace ,
14+ } from "element-plus"
15+ import { type Component , computed , defineComponent , type FunctionalComponent , h , type StyleValue } from "vue"
16+ import { verifyCanModify } from "../../common"
17+ import { useLimitAction , useLimitTable } from "../../context"
1618import Rule from "./Rule"
1719
1820type Props = {
1921 value : timer . limit . Item
22+ onEnabledChange ?: ( id : number ) => void
2023}
2124
22- type Flag = keyof timer . limit . Rule & ( 'enabled' | 'locked ' | 'allowDelay' )
23- const isFlag = createStringUnionGuard < Flag > ( 'allowDelay' , 'enabled' , 'locked' )
25+ const FLAGS : ( keyof timer . limit . Item & 'enabled' | 'allowDelay ' | 'locked' ) [ ] = [ 'enabled' , 'allowDelay' , 'locked' ] as const
26+ type Flag = typeof FLAGS [ number ]
2427
25- const FLAG_GROUP : [ Flag , Component ] [ ] = [
26- [ 'enabled' , CircleCheck ] ,
27- [ 'allowDelay' , Clock ] ,
28- [ 'locked' , Lock ] ,
29- ]
28+ const FLAG_ICON : { [ flag in Flag ] : Component } = {
29+ enabled : CircleCheck ,
30+ allowDelay : Clock ,
31+ locked : Lock ,
32+ }
33+
34+ const FlagRadioGroup = defineComponent < { value : timer . limit . Item } > ( props => {
35+ const { changeEnabled, changeDelay, changeLocked } = useLimitTable ( )
36+
37+ const selected = computed ( ( ) => FLAGS . filter ( flag => props . value [ flag ] ) )
38+ const handleChange = ( newVal : CheckboxValueType [ ] ) => {
39+ const newEnabled = newVal . includes ( 'enabled' )
40+ const newAllowDelay = newVal . includes ( 'allowDelay' )
41+ const newLocked = newVal . includes ( 'locked' )
42+
43+ if ( newEnabled !== props . value . enabled ) {
44+ changeEnabled ( props . value , newEnabled )
45+ }
46+ if ( newAllowDelay !== props . value . allowDelay ) {
47+ changeDelay ( props . value , newAllowDelay )
48+ }
49+ if ( newLocked !== props . value . locked ) {
50+ changeLocked ( props . value , newLocked )
51+ }
52+ }
3053
31- const FlagRadioGroup = defineComponent < ModelValue < Record < Flag , boolean > > > ( props => {
32- const selected = computed ( ( ) => Object . entries ( props . modelValue ) . filter ( ( [ _ , v ] ) => ! ! v ) . map ( e => e [ 0 ] as Flag ) )
3354 return ( ) => (
34- < ElCheckboxGroup
35- modelValue = { selected . value }
36- onChange = { selected => {
37- const newVal = { ...props . modelValue }
38- selected . forEach ( s => isFlag ( s ) && ( newVal [ s ] = true ) )
39- props . onChange ?.( newVal )
40- } }
41- >
42- { FLAG_GROUP . map ( ( [ value , icon ] ) => (
55+ < ElCheckboxGroup modelValue = { selected . value } onChange = { handleChange } >
56+ { FLAGS . map ( value => (
4357 < ElCheckboxButton value = { value } >
4458 < span style = { { margin : '-6px' } satisfies StyleValue } >
45- < ElIcon size = 'small' > { h ( icon ) } </ ElIcon >
59+ < ElIcon size = 'small' > { h ( FLAG_ICON [ value ] ) } </ ElIcon >
4660 </ span >
4761 </ ElCheckboxButton >
4862 ) ) }
4963 </ ElCheckboxGroup >
5064 )
51- } , {
52- props : [ 'modelValue' , 'onChange' ]
53- } )
65+ } , { props : [ 'value' ] } )
5466
5567const CARD_PADDING = 10
5668
@@ -72,6 +84,23 @@ const Divider: FunctionalComponent<{}> = () => {
7284 return < ElDivider style = { { marginBlock : '6px' , marginInline, width } satisfies StyleValue } />
7385}
7486
87+ const EffectiveDays : FunctionalComponent < { weekdays ?: number [ ] } > = ( { weekdays = [ ] } ) => {
88+ const weekdayNum = weekdays ?. length
89+ let text : string = ''
90+ let type : TagProps [ 'type' ] | undefined = undefined
91+ if ( ! weekdayNum || weekdayNum === 7 ) {
92+ text = t ( msg => msg . calendar . range . everyday )
93+ type = 'success'
94+ } else if ( weekdayNum === 1 ) {
95+ text = ALL_WEEKDAYS [ weekdays [ 0 ] ]
96+ } else {
97+ const firstDay = ALL_WEEKDAYS [ weekdays [ 0 ] ]
98+ text = `${ firstDay } ...${ weekdayNum } `
99+ }
100+
101+ return < ElTag size = "small" type = { type } > { text } </ ElTag >
102+ }
103+
75104const _default = defineComponent < Props > ( props => {
76105 const { deleteRow } = useLimitTable ( )
77106 const { modify } = useLimitAction ( )
@@ -85,29 +114,6 @@ const _default = defineComponent<Props>(props => {
85114 . then ( ( ) => deleteRow ( props . value ) )
86115 . catch ( ( ) => { /** Do nothing */ } )
87116
88- const renderEffectiveTag = ( weekdays : number [ ] | undefined ) => {
89- if ( ! weekdays || weekdays . length === 0 || weekdays . length === 7 ) {
90- return (
91- < ElTag size = "small" type = "success" >
92- { t ( msg => msg . calendar . range . everyday ) }
93- </ ElTag >
94- )
95- }
96-
97- if ( weekdays . length === 1 ) {
98- return (
99- < ElTag size = "small" >
100- { ALL_WEEKDAYS ?. [ weekdays [ 0 ] ] }
101- </ ElTag >
102- )
103- }
104-
105- const firstDay = ALL_WEEKDAYS ?. [ weekdays [ 0 ] ]
106- const allDays = weekdays . map ( w => ALL_WEEKDAYS ?. [ w ] ) . join ( '、' )
107-
108- return < ElTag size = "small" > { firstDay } ...${ allDays . length } </ ElTag >
109- }
110-
111117 const clz = useStyle ( )
112118
113119 return ( ) => (
@@ -116,9 +122,9 @@ const _default = defineComponent<Props>(props => {
116122 < Flex justify = "space-between" align = "center" >
117123 < Flex align = "center" gap = { 8 } >
118124 < span style = { { fontWeight : 'bold' } } >
119- { props . value . name || '- '}
125+ { props . value . name ?? 'Unnamed '}
120126 </ span >
121- { renderEffectiveTag ( props . value . weekdays ) }
127+ < EffectiveDays weekdays = { props . value . weekdays } />
122128 </ Flex >
123129 < ElButton
124130 size = "small"
@@ -139,7 +145,7 @@ const _default = defineComponent<Props>(props => {
139145 < Divider />
140146 { /* Footer Button */ }
141147 < Flex justify = 'between' >
142- < FlagRadioGroup modelValue = { props . value } onChange = { ( ) => { /** todo */ } } />
148+ < FlagRadioGroup value = { props . value } />
143149 < ElButton text icon = { EditPen } onClick = { handleModify } size = 'small' />
144150 </ Flex >
145151 </ Flex >
0 commit comments