Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨feat(grid): render select and multi select #WIK-16262 #44

Merged
merged 4 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions packages/grid/src/components/cell-editors/cell-editor.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
@use 'ngx-tethys/styles/variables.scss';
@use './progress/progress-editor.component.scss';

.date-time-cell-editor {
.thy-calendar-picker {
height: 100%;
Expand All @@ -16,10 +19,27 @@
}

.number-cell-editor {
.thy-input-number{
.thy-input-number {
.input-number-input {
border-width: 2px;
}
}

}

.select-cell-editor {
&:not(.tag) {
.select-control-multiple {
.choice-remove-link {
.thy-icon-close {
color: variables.$gray-700;
}
}
}
}
}

.grid-cell-editor {
.select-cell-editor .form-control {
height: auto;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<thy-select
[(ngModel)]="modelValue"
[thyAutoExpand]="true"
[thyAllowClear]="true"
[thyMode]="field().isMultiple ? 'multiple' : ''"
[thyPreset]="'tag'"
(thyOnExpandStatusChange)="updateValue($event)"
>
<ng-template #selectedDisplay let-option>
<select-cell-view [field]="field()" [displayOption]="option"></select-cell-view>
</ng-template>
@for (option of selectOptions(); track option._id) {
<thy-option [thyValue]="option._id" [thyRawValue]="option" [thyShowOptionCustom]="true" [thyLabelText]="option.text">
<select-option [field]="field()" [displayOption]="option"></select-option>
</thy-option>
}
</thy-select>
Original file line number Diff line number Diff line change
@@ -1,36 +1,54 @@
import { NgForOf, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, Input } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ThySelect } from 'ngx-tethys/select';
import { AbstractEditCellEditor } from '../abstract-cell-editor.component';
import { ThyTag } from 'ngx-tethys/tag';
import { ThyDot } from 'ngx-tethys/dot';
import { ThyFlexibleText } from 'ngx-tethys/flexible-text';
import { ThyIcon } from 'ngx-tethys/icon';
import { ThySelect } from 'ngx-tethys/select';
import { ThyOption } from 'ngx-tethys/shared';
import { AITableSelectOption, AITableField } from '../../../core';

export interface AITableSingleSelectField extends AITableField<AITableSelectOption> {
options: AITableSelectOption[];
}
import { ThyTag } from 'ngx-tethys/tag';
import { ThyTooltipModule } from 'ngx-tethys/tooltip';
import { SelectOptionPipe } from '../../../pipes';
import { AITableSelectOptionStyle, AITableSingleSelectField } from '../../../types';
import { SelectOptionComponent } from '../../cell-views/select/option.component';
import { SelectCellViewComponent } from '../../cell-views/select/select-view.component';
import { AbstractEditCellEditor } from '../abstract-cell-editor.component';

@Component({
selector: 'single-select-cell-editor',
template: `<thy-select [(ngModel)]="modelValue" [thyAutoExpand]="true" (thyOnExpandStatusChange)="updateValue($event)">
<thy-option *ngFor="let option of selectOptions()" [thyValue]="option._id" [thyLabelText]="option.text"> </thy-option>
</thy-select> `,
templateUrl: './select-editor.component.html',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'd-block h-100'
class: 'd-block h-100 select-cell-editor',
'[class.tag]': 'field()!.optionStyle === AITableSelectOptionStyle.tag'
},
imports: [NgIf, NgForOf, FormsModule, ThySelect, ThyOption, ThyTag, ThyIcon]
imports: [
FormsModule,
NgTemplateOutlet,
ThySelect,
ThyOption,
ThyTag,
ThyIcon,
ThyTooltipModule,
ThyDot,
ThyFlexibleText,
SelectOptionPipe,
SelectCellViewComponent,
SelectOptionComponent
]
})
export class SelectCellEditorComponent extends AbstractEditCellEditor<string, AITableSingleSelectField> {
@Input() isMultiple!: boolean;

selectOptions = computed(() => {
return this.field().options;
});

optionStyle = computed(() => {
return (this.field() as AITableSingleSelectField).optionStyle || AITableSelectOptionStyle.tag;
});

AITableSelectOptionStyle = AITableSelectOptionStyle;

constructor() {
super();
}
Expand Down
1 change: 1 addition & 0 deletions packages/grid/src/components/cell-views/cell-views.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@use 'ngx-tethys/styles/variables.scss';
Maple13 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@for (option of selectedOptions(); track option._id; let i = $index) {
@if (i + 1 <= maxShowCount) {
<select-cell-view [field]="field()" [displayOption]="option"></select-cell-view>
}
}
@if (selectedOptions() && maxShowCount < selectedOptions().length) {
<thy-tag class="cursor-pointer" [class.multi-property-value-hidden]="maxShowCount >= selectedOptions().length" [thyShape]="tagShape()">
<span class="text-truncate">+{{ selectedOptions().length - maxShowCount }}</span>
</thy-tag>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
import { ThyTag } from 'ngx-tethys/tag';
import { AITableField, AITableRecord, AITableSelectOption } from '../../../core';
import { SelectOptionPipe } from '../../../pipes';
import { AITableSelectOptionStyle, AITableSingleSelectField } from '../../../types';
import { SelectCellViewComponent } from './select-view.component';

@Component({
selector: 'multi-select-view',
templateUrl: './multi-select-view.component.html',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'd-flex multi-select-view'
},
imports: [ThyTag, SelectCellViewComponent, SelectOptionPipe],
providers: [SelectOptionPipe]
})
export class MultiSelectViewComponent {
field = input.required<AITableField>();

record = input.required<AITableRecord>();

AITableSelectOptionStyle = AITableSelectOptionStyle;

maxShowCount = 2;

private selectOptionPipe = inject(SelectOptionPipe);

selectedOptions = computed<AITableSelectOption[]>(() => {
Maple13 marked this conversation as resolved.
Show resolved Hide resolved
const values = this.record().values[this.field()._id] ?? [];
return values.map((id: string) => {
return this.selectOptionPipe.transform(id, (this.field() as AITableSingleSelectField).options);
});
});

optionStyle = computed(() => {
return (this.field() as AITableSingleSelectField).optionStyle || AITableSelectOptionStyle.tag;
});

tagShape = computed(() => {
return this.optionStyle() === AITableSelectOptionStyle.tag ? 'pill' : 'rectangle';
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@if (displayOption(); as displayOption) {
@switch (optionStyle()) {
@case (AITableSelectOptionStyle.dot) {
@if (displayOption.bg_color) {
<thy-dot [thyColor]="displayOption.bg_color" [thySize]="'sm'" class="mr-2"></thy-dot>
}
<ng-template [ngTemplateOutlet]="flexibleText"></ng-template>
}
@case (AITableSelectOptionStyle.tag) {
@if (displayOption.bg_color || displayOption.color; as color) {
<thy-tag thyTheme="fill" thyShape="pill" [thyColor]="color">
@if (displayOption['icon']) {
<thy-icon class="text-white" [thyIconName]="displayOption['icon']"></thy-icon>
}
<ng-template [ngTemplateOutlet]="flexibleText"></ng-template>
</thy-tag>
}
}
@case (AITableSelectOptionStyle.piece) {
@if (displayOption.bg_color || displayOption.color; as color) {
<thy-dot thyShape="square" [thyColor]="color" [thySize]="'sm'" class="mr-2"></thy-dot>
}
<ng-template [ngTemplateOutlet]="flexibleText"></ng-template>
}
@default {
@if (displayOption['icon']) {
<thy-icon [thyIconName]="displayOption['icon']" [style.color]="displayOption.color"></thy-icon>
}
<ng-template [ngTemplateOutlet]="flexibleText"></ng-template>
}
}
}

<ng-template #flexibleText>
Maple13 marked this conversation as resolved.
Show resolved Hide resolved
@if (displayOption()!.text || displayOption()!['name'] || displayOption()!['title']; as value) {
<span thyFlexibleText [thyTooltipContent]="value">{{ value }}</span>
}
</ng-template>
31 changes: 31 additions & 0 deletions packages/grid/src/components/cell-views/select/option.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
import { ThyDot } from 'ngx-tethys/dot';
import { ThyFlexibleText } from 'ngx-tethys/flexible-text';
import { ThyIcon } from 'ngx-tethys/icon';
import { ThyTag } from 'ngx-tethys/tag';
import { ThyTooltipModule } from 'ngx-tethys/tooltip';
import { AITableField, AITableSelectOption } from '../../../core';
import { AITableSelectOptionStyle, AITableSingleSelectField } from '../../../types';

@Component({
selector: 'select-option',
templateUrl: './option.component.html',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'd-flex align-items-center select-option'
},
imports: [NgTemplateOutlet, ThyTag, ThyIcon, ThyTooltipModule, ThyDot, ThyFlexibleText]
})
export class SelectOptionComponent {
field = input.required<AITableField>();

displayOption = input.required<AITableSelectOption>();

optionStyle = computed(() => {
return (this.field() as AITableSingleSelectField).optionStyle || AITableSelectOptionStyle.tag;
});

AITableSelectOptionStyle = AITableSelectOptionStyle;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@if (optionStyle() === AITableSelectOptionStyle.tag) {
<select-option [field]="field()" [displayOption]="displayOption()"></select-option>
} @else {
<div thyTag class="mb-1 mr-1">
<select-option [field]="field()" [displayOption]="displayOption()"></select-option>
</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
import { ThyTag } from 'ngx-tethys/tag';
import { AITableField, AITableSelectOption } from '../../../core';
import { AITableSelectOptionStyle, AITableSingleSelectField } from '../../../types';
import { SelectOptionComponent } from './option.component';

@Component({
selector: 'select-cell-view',
templateUrl: './select-view.component.html',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'd-flex select-cell-view',
'[class.mb-1]': 'optionStyle() === AITableSelectOptionStyle.tag',
'[class.mr-1]': 'optionStyle() === AITableSelectOptionStyle.tag'
},
imports: [ThyTag, SelectOptionComponent]
})
export class SelectCellViewComponent {
field = input.required<AITableField>();

displayOption = input.required<AITableSelectOption>();

optionStyle = computed(() => {
return (this.field() as AITableSingleSelectField).optionStyle || AITableSelectOptionStyle.tag;
});

AITableSelectOptionStyle = AITableSelectOptionStyle;

maxShowCount = 2;
}
3 changes: 3 additions & 0 deletions packages/grid/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ export * from './cell-editors/number/number-editor.component';
export * from './cell-editors/progress/progress-editor.component';
export * from './cell-editors/rating/rating-editor.component';
export * from './cell-editors/text/text-editor.component';
export * from './cell-views/select/multi-select-view.component';
export * from './cell-views/select/option.component';
export * from './cell-views/select/select-view.component';
export * from './field-property-editor/field-property-editor.component';
7 changes: 6 additions & 1 deletion packages/grid/src/core/constants/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ export const BasicFields = [
icon: 'check-circle',
width: 200
},
// 多选
{
type: AITableFieldType.select,
name: '多选',
icon: 'list-check',
width: 200
},
{
type: AITableFieldType.number,
name: '数字',
Expand Down
8 changes: 6 additions & 2 deletions packages/grid/src/grid.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@
@switch (field.type) {
@case (AITableFieldType.select) {
@if (!field.isMultiple && record.values[field._id] | selectOption: field['options']; as selectedOption) {
<thy-tag [thyColor]="selectedOption!.color!">{{ selectedOption.text }}</thy-tag>
<select-cell-view [field]="field" [displayOption]="selectedOption"></select-cell-view>
Maple13 marked this conversation as resolved.
Show resolved Hide resolved
} @else {
<div class="d-flex align-items-center">
<multi-select-view [field]="field" [record]="record"></multi-select-view>
</div>
}
}
@case (AITableFieldType.date) {
Expand Down Expand Up @@ -157,4 +161,4 @@
</div>
</div>

<div #activeBorder class="active-border"></div>
<div #activeBorder class="active-border"></div>
22 changes: 17 additions & 5 deletions packages/grid/src/grid.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
import { ThyAction } from 'ngx-tethys/action';
import { ThyAvatar, ThyAvatarModule, ThyAvatarService, ThyDefaultAvatarService } from 'ngx-tethys/avatar';
import { ThyCheckboxModule } from 'ngx-tethys/checkbox';
import { ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
import { ThyDropdownDirective, ThyDropdownMenuComponent } from 'ngx-tethys/dropdown';
Expand All @@ -27,7 +28,7 @@ import { ThyRate } from 'ngx-tethys/rate';
import { ThyStopPropagationDirective } from 'ngx-tethys/shared';
import { ThyTag } from 'ngx-tethys/tag';
import { mergeWith } from 'rxjs/operators';
import { ProgressEditorComponent } from './components';
import { MultiSelectViewComponent, ProgressEditorComponent, SelectCellViewComponent } from './components';
import { FieldMenu } from './components/field-menu/field-menu.component';
import { AITableFieldPropertyEditor } from './components/field-property-editor/field-property-editor.component';
import { DBL_CLICK_EDIT_TYPE, DefaultFieldMenus, MOUSEOVER_EDIT_TYPE } from './constants';
Expand All @@ -49,15 +50,14 @@ import { AI_TABLE_GRID_FIELD_SERVICE_MAP, AITableGridFieldService } from './serv
import { AITableGridSelectionService } from './services/selection.service';
import { AIFieldConfig, AITableFieldMenuItem, AITableReferences } from './types';
import { buildGridData } from './utils';
import { ThyAvatarModule } from 'ngx-tethys/avatar';

@Component({
selector: 'ai-table-grid',
templateUrl: './grid.component.html',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'ai-table-grid'
class: 'ai-table-grid '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

空格

},
imports: [
NgForOf,
Expand All @@ -83,9 +83,21 @@ import { ThyAvatarModule } from 'ngx-tethys/avatar';
ProgressEditorComponent,
ThyAvatarModule,
NgTemplateOutlet,
IsSelectRecordPipe
IsSelectRecordPipe,
ThyAvatar,
Maple13 marked this conversation as resolved.
Show resolved Hide resolved
ProgressEditorComponent,
SelectCellViewComponent,
MultiSelectViewComponent
],
providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService]
providers: [
{
provide: ThyAvatarService,
useClass: ThyDefaultAvatarService
},
AITableGridEventService,
AITableGridFieldService,
AITableGridSelectionService
]
})
export class AITableGrid implements OnInit {
aiRecords = model.required<AITableRecords>();
Expand Down
Loading