Skip to content

Commit

Permalink
Merge pull request #42 from daichen-daisy/main
Browse files Browse the repository at this point in the history
1st round refactor
  • Loading branch information
daichen-daisy authored May 30, 2023
2 parents 99d313f + 4f65d5c commit aa77c46
Show file tree
Hide file tree
Showing 58 changed files with 3,045 additions and 2,850 deletions.
846 changes: 0 additions & 846 deletions src/components/OrgTree.vue

This file was deleted.

21 changes: 21 additions & 0 deletions src/components/application/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface Application {
/** 应用 ID */
id: string;
/** 应用名称 */
name?: string;
/** 应用描述 */
description?: string;
/** 应用密钥 */
secret_key?: string;
}

export interface ApplicationPostData {
/** 应用名称 */
name?: string;
/** 应用描述 */
description?: string;
}

export interface ApplicationPostError {
name?: string;
}
56 changes: 56 additions & 0 deletions src/components/common/BooleanChip.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<q-chip
square
size="12px"
:label="value ? `${trueLabel}` : `${falseLabel}`"
class="text-weight-bold q-pa-sm q-ml-none"
:class="value ? 'chip-status-on' : 'chip-status-off'"
/>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'BooleanChip',
props: {
value: {
type: Boolean,
default: false,
},
trueLabel: {
type: String,
default: 'YES',
},
falseLabel: {
type: String,
default: 'NO',
},
},
});
</script>

<style lang="scss" scoped>
.chip-status-on {
background-color: $blue-1;
color: $blue-14;
}
.chip-status-off {
background-color: $red-1;
color: $red-8;
}
.body--dark {
.chip-status-on {
background-color: rgb(54, 72, 113);
color: $blue-1;
}
.chip-status-off {
background-color: #6f3a3a;
color: $red-1;
}
}
</style>
83 changes: 83 additions & 0 deletions src/components/common/ChipGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<template>
<q-chip
v-for="(chip, idx) in chips"
:key="idx"
size="12px"
:color="selectedChips.includes(chip.id) ? 'primary' : 'secondary'"
:text-color="selectedChips.includes(chip.id) ? 'white' : ''"
class="q-ml-none"
:clickable="clickable"
:square="square"
@click="clickChip(chip)"
>
<span class="material-icons-outlined q-pr-xs">
{{ icon }}
</span>
{{ chip.name }}
</q-chip>
</template>

<script lang="ts">
import { defineComponent, PropType, ref } from 'vue';
import { ChipGroupItem } from './type';
export default defineComponent({
name: 'ChipChipGroup',
props: {
chips: {
type: Array as PropType<ChipGroupItem[]>,
default: () => {
return [];
},
},
clickable: {
type: Boolean,
default: false,
},
square: {
type: Boolean,
default: false,
},
icon: {
type: String,
default: '',
},
selection: {
type: String,
default: 'single',
},
},
emits: ['selectedChange'],
setup() {
return {
selectedChips: ref<string[]>([]),
};
},
methods: {
clickChip(chip: ChipGroupItem) {
if (!this.clickable) return;
if (this.selection === 'multiple') {
if (this.selectedChips.includes(chip.id)) {
this.selectedChips = this.selectedChips.filter(
(tid) => tid != chip.id
);
} else {
this.selectedChips.push(chip.id);
}
} else if (this.selection === 'single') {
this.selectedChips = this.selectedChips.includes(chip.id)
? []
: [chip.id];
}
this.$emit('selectedChange', this.selectedChips);
},
},
});
</script>

<style lang="scss" scoped></style>
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
<template>
<q-item-label class="text-caption hint-label">
{{ name }}
{{ text }}
<q-icon
v-if="required"
name="emergency"
size="8px"
color="negative"
style="vertical-align: top"
class="assistant-icon"
/>
<q-icon
v-if="hint"
name="error_outline"
size="14px"
class="q-ml-xs"
style="vertical-align: top"
class="q-ml-xs assistant-icon"
>
<q-tooltip anchor="center right" self="center start">
{{ hint }}
Expand All @@ -29,7 +28,7 @@ export default defineComponent({
name: 'FieldLabel',
props: {
name: {
text: {
type: String,
default: '',
},
Expand All @@ -45,4 +44,8 @@ export default defineComponent({
});
</script>

<style lang="scss" scoped></style>
<style lang="scss" scoped>
.assistant-icon {
vertical-align: top;
}
</style>
5 changes: 5 additions & 0 deletions src/components/type.ts → src/components/common/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ export interface MenuButton {
/** 禁用按钮提示信息 */
disableHint?: string;
}

export interface ChipGroupItem {
id: string;
name: string;
}
8 changes: 6 additions & 2 deletions src/components/form/CascadeItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@
:selected="child.selected"
:opt-label="optLabel"
:opt-value="optValue"
@update:model="onValueUpdated"
@update:model="
(value: CascadeOption[]) => {
onValueUpdated(value);
}
"
/>
</q-list>
</q-menu>
Expand Down Expand Up @@ -76,7 +80,7 @@ export default defineComponent({
this.$emit('update:model', [this.scope]);
},
onValueUpdated(selected: CascadeOption) {
onValueUpdated(selected: CascadeOption[]) {
const newSelected = [this.scope].concat(selected);
this.$emit('update:model', newSelected);
},
Expand Down
146 changes: 146 additions & 0 deletions src/components/form/SearchableMultipleSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<template>
<q-select
ref="select"
v-model="selected"
:options="options"
:placeholder="placeholder"
:option-value="optValue"
:option-label="optLabel"
filled
dense
use-input
hide-dropdown-icon
hide-bottom-space
multiple
map-options
virtual-scroll-slice-size="5"
@filter="searchOptions"
@update:model-value="(value) => clearFilter(value)"
>
<template #no-option>
<q-item>
<q-item-section class="text-grey"> 找不到任何匹配项 </q-item-section>
</q-item>
</template>
<template #selected-item="scope">
<q-chip
removable
dense
:tabindex="scope.tabindex"
color="primary"
text-color="white"
class="q-pa-sm"
:label="scope.opt.name"
@remove="scope.removeAtIndex(scope.index)"
/>
</template>
<template #option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<boolean-chip
:value="!scope.opt.is_deleted"
true-label="正常"
false-label="禁用"
/>
</q-item-section>
<q-item-section>
<q-item-label>
{{ scope.opt[optLabel] }}
{{ scope.opt.username }}
</q-item-label>
<q-item-label caption>
{{ scope.opt.mobile }}
{{ scope.opt.email }}
</q-item-label>
<slot name="option-caption-label" :opt="scope.opt" />
</q-item-section>
<q-item-section v-if="!!scope.opt.org_type" side>
<chip-group :chips="[scope.opt.org_type]" square />
</q-item-section>
</q-item>
</template>
</q-select>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { QSelect } from 'quasar';
export default defineComponent({
name: 'SearchableMultipleSelect',
props: {
modelValue: {
type: Object,
default: () => {
return {};
},
},
optValue: {
type: String,
default: 'id',
},
optLabel: {
type: String,
default: 'name',
},
placeholder: {
type: String,
default: '输入关键字进行搜索',
},
optionApiUrl: {
type: String,
default: null,
},
optionApiParams: {
type: Object,
default: () => {
return {};
},
},
},
emits: ['update:modelValue'],
setup() {
return {
options: ref([]),
selected: ref({}),
};
},
created() {
this.selected = this.modelValue;
},
methods: {
searchOptions(
val: string,
update: (fn: () => void) => void,
abort: () => void
) {
const kw = val.trim();
if (kw === '') {
abort();
return;
}
update(async () => {
const resp = await this.$api.post(
this.optionApiUrl,
Object.assign({}, this.optionApiParams, {
q: kw,
})
);
this.options = resp.data.rows;
});
},
clearFilter(val: string) {
this.$emit('update:modelValue', val);
(this.$refs.select as QSelect).updateInputValue('');
},
},
});
</script>

<style lang="scss" scoped></style>
Loading

0 comments on commit aa77c46

Please sign in to comment.