Skip to content

Commit f67fbdc

Browse files
committed
Simplified attribute_service genericization by removing customizable attributesKey
1 parent fb07e63 commit f67fbdc

5 files changed

Lines changed: 49 additions & 91 deletions

File tree

src/plugins/dashboard/public/attribute_service/attribute_service.test.ts

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,25 @@
1717
* under the License.
1818
*/
1919

20+
import { ATTRIBUTE_SERVICE_KEY } from './attribute_service';
2021
import { mockAttributeService } from './attribute_service_mock';
2122
import { coreMock } from '../../../../core/public/mocks';
2223

23-
interface DefaultTestAttributes {
24+
interface TestAttributes {
2425
title: string;
2526
testAttr1?: string;
2627
testAttr2?: { array: unknown[]; testAttr3: string };
2728
}
2829

29-
interface DefaultByValueInput {
30+
interface TestByValueInput {
3031
id: string;
31-
attributes: DefaultTestAttributes;
32-
}
33-
34-
const customAttributesKey = 'reallyNeatAttributesKey';
35-
interface CustomTestByValueInput {
36-
id: string;
37-
[customAttributesKey]: DefaultTestAttributes;
32+
[ATTRIBUTE_SERVICE_KEY]: TestAttributes;
3833
}
3934

4035
describe('attributeService', () => {
4136
const defaultTestType = 'defaultTestType';
42-
let attributes: DefaultTestAttributes;
43-
let byValueInput: DefaultByValueInput;
37+
let attributes: TestAttributes;
38+
let byValueInput: TestByValueInput;
4439
let byReferenceInput: { id: string; savedObjectId: string };
4540

4641
beforeEach(() => {
@@ -60,12 +55,10 @@ describe('attributeService', () => {
6055
});
6156

6257
describe('determining input type', () => {
63-
const defaultAttributeService = mockAttributeService<DefaultTestAttributes>(defaultTestType);
64-
const customAttributeService = mockAttributeService<
65-
DefaultTestAttributes,
66-
typeof customAttributesKey,
67-
CustomTestByValueInput
68-
>(defaultTestType);
58+
const defaultAttributeService = mockAttributeService<TestAttributes>(defaultTestType);
59+
const customAttributeService = mockAttributeService<TestAttributes, TestByValueInput>(
60+
defaultTestType
61+
);
6962

7063
it('can determine input type given default types', () => {
7164
expect(
@@ -85,7 +78,7 @@ describe('attributeService', () => {
8578
expect(
8679
customAttributeService.inputIsRefType({
8780
id: '456',
88-
[customAttributesKey]: { title: 'wow I am by value' },
81+
[ATTRIBUTE_SERVICE_KEY]: { title: 'wow I am by value' },
8982
})
9083
).toBeFalsy();
9184
});
@@ -97,7 +90,7 @@ describe('attributeService', () => {
9790
core.savedObjects.client.get = jest.fn().mockResolvedValueOnce({
9891
attributes,
9992
});
100-
const attributeService = mockAttributeService<DefaultTestAttributes>(
93+
const attributeService = mockAttributeService<TestAttributes>(
10194
defaultTestType,
10295
undefined,
10396
core
@@ -106,38 +99,22 @@ describe('attributeService', () => {
10699
});
107100

108101
it('returns attributes when when given value type input', async () => {
109-
const attributeService = mockAttributeService<DefaultTestAttributes>(defaultTestType);
102+
const attributeService = mockAttributeService<TestAttributes>(defaultTestType);
110103
expect(await attributeService.unwrapAttributes(byValueInput)).toEqual(attributes);
111104
});
112105

113-
it('returns attributes with custom key when given value type input', async () => {
114-
const customAttributeService = mockAttributeService<
115-
DefaultTestAttributes,
116-
typeof customAttributesKey,
117-
CustomTestByValueInput
118-
>(defaultTestType, { attributesKey: customAttributesKey });
119-
expect(
120-
await customAttributeService.unwrapAttributes({
121-
id: '456',
122-
[customAttributesKey]: attributes,
123-
})
124-
).toEqual(attributes);
125-
});
126-
127106
it('runs attributes through a custom unwrap method', async () => {
128107
const core = coreMock.createStart();
129108
core.savedObjects.client.get = jest.fn().mockResolvedValueOnce({
130109
attributes,
131110
});
132-
const attributeService = mockAttributeService<DefaultTestAttributes>(
111+
const attributeService = mockAttributeService<TestAttributes>(
133112
defaultTestType,
134113
{
135-
customUnwrapMethod: (savedObject) => {
136-
return {
137-
...savedObject.attributes,
138-
testAttr2: { array: [1, 2, 3, 4, 5], testAttr3: 'kibanana' },
139-
};
140-
},
114+
customUnwrapMethod: (savedObject) => ({
115+
...savedObject.attributes,
116+
testAttr2: { array: [1, 2, 3, 4, 5], testAttr3: 'kibanana' },
117+
}),
141118
},
142119
core
143120
);
@@ -150,24 +127,13 @@ describe('attributeService', () => {
150127

151128
describe('wrapping attributes', () => {
152129
it('returns given attributes when use ref type is false', async () => {
153-
const attributeService = mockAttributeService<DefaultTestAttributes>(defaultTestType);
130+
const attributeService = mockAttributeService<TestAttributes>(defaultTestType);
154131
expect(await attributeService.wrapAttributes(attributes, false)).toEqual({ attributes });
155132
});
156133

157-
it('returns given attributes with custom key when use ref type is false', async () => {
158-
const attributeService = mockAttributeService<
159-
DefaultTestAttributes,
160-
typeof customAttributesKey,
161-
CustomTestByValueInput
162-
>(defaultTestType, { attributesKey: customAttributesKey });
163-
expect(await attributeService.wrapAttributes(attributes, false)).toEqual({
164-
[customAttributesKey]: attributes,
165-
});
166-
});
167-
168134
it('updates existing saved object with new attributes when given id', async () => {
169135
const core = coreMock.createStart();
170-
const attributeService = mockAttributeService<DefaultTestAttributes>(
136+
const attributeService = mockAttributeService<TestAttributes>(
171137
defaultTestType,
172138
undefined,
173139
core
@@ -187,7 +153,7 @@ describe('attributeService', () => {
187153
core.savedObjects.client.create = jest.fn().mockResolvedValueOnce({
188154
id: '678',
189155
});
190-
const attributeService = mockAttributeService<DefaultTestAttributes>(
156+
const attributeService = mockAttributeService<TestAttributes>(
191157
defaultTestType,
192158
undefined,
193159
core
@@ -199,8 +165,8 @@ describe('attributeService', () => {
199165
});
200166

201167
it('uses custom save method when given an id', async () => {
202-
const customSaveMethod = jest.fn().mockReturnValue({ id: '678' });
203-
const attributeService = mockAttributeService<DefaultTestAttributes>(defaultTestType, {
168+
const customSaveMethod = jest.fn().mockReturnValue({ id: '123' });
169+
const attributeService = mockAttributeService<TestAttributes>(defaultTestType, {
204170
customSaveMethod,
205171
});
206172
expect(await attributeService.wrapAttributes(attributes, true, byReferenceInput)).toEqual(
@@ -215,13 +181,13 @@ describe('attributeService', () => {
215181

216182
it('uses custom save method given no id', async () => {
217183
const customSaveMethod = jest.fn().mockReturnValue({ id: '678' });
218-
const attributeService = mockAttributeService<DefaultTestAttributes>(defaultTestType, {
184+
const attributeService = mockAttributeService<TestAttributes>(defaultTestType, {
219185
customSaveMethod,
220186
});
221187
expect(await attributeService.wrapAttributes(attributes, true)).toEqual({
222188
savedObjectId: '678',
223189
});
224-
expect(customSaveMethod).toHaveBeenCalledWith(defaultTestType, attributes);
190+
expect(customSaveMethod).toHaveBeenCalledWith(defaultTestType, attributes, undefined);
225191
});
226192
});
227193
});

src/plugins/dashboard/public/attribute_service/attribute_service.tsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,9 @@ import {
4949
* can also be used as a higher level wrapper to transform an embeddable input shape that references a saved object
5050
* into an embeddable input shape that contains that saved object's attributes by value.
5151
*/
52-
export const ATTRIBUTE_SERVICE_DEFAULT_KEY = 'attributes';
52+
export const ATTRIBUTE_SERVICE_KEY = 'attributes';
5353

54-
export interface AttributeServiceOptions<
55-
A extends { title: string },
56-
K extends string = typeof ATTRIBUTE_SERVICE_DEFAULT_KEY
57-
> {
58-
attributesKey?: K;
54+
export interface AttributeServiceOptions<A extends { title: string }> {
5955
customSaveMethod?: (
6056
type: string,
6157
attributes: A,
@@ -66,14 +62,12 @@ export interface AttributeServiceOptions<
6662

6763
export class AttributeService<
6864
SavedObjectAttributes extends { title: string },
69-
AttributesKey extends string = typeof ATTRIBUTE_SERVICE_DEFAULT_KEY,
70-
ValType extends EmbeddableInput &
71-
{ [key in AttributesKey]: SavedObjectAttributes } = EmbeddableInput &
72-
{ [key in AttributesKey]: SavedObjectAttributes },
65+
ValType extends EmbeddableInput & {
66+
[ATTRIBUTE_SERVICE_KEY]: SavedObjectAttributes;
67+
} = EmbeddableInput & { [ATTRIBUTE_SERVICE_KEY]: SavedObjectAttributes },
7368
RefType extends SavedObjectEmbeddableInput = SavedObjectEmbeddableInput
7469
> {
7570
private embeddableFactory?: EmbeddableFactory;
76-
private attributesKey: AttributesKey;
7771

7872
constructor(
7973
private type: string,
@@ -86,9 +80,8 @@ export class AttributeService<
8680
private i18nContext: I18nStart['Context'],
8781
private toasts: NotificationsStart['toasts'],
8882
getEmbeddableFactory?: EmbeddableStart['getEmbeddableFactory'],
89-
private options?: AttributeServiceOptions<SavedObjectAttributes, AttributesKey>
83+
private options?: AttributeServiceOptions<SavedObjectAttributes>
9084
) {
91-
this.attributesKey = options?.attributesKey || (ATTRIBUTE_SERVICE_DEFAULT_KEY as AttributesKey);
9285
if (getEmbeddableFactory) {
9386
const factory = getEmbeddableFactory(this.type);
9487
if (!factory) {
@@ -107,7 +100,7 @@ export class AttributeService<
107100
? this.options?.customUnwrapMethod(savedObject)
108101
: { ...savedObject.attributes };
109102
}
110-
return input[this.attributesKey];
103+
return input[ATTRIBUTE_SERVICE_KEY];
111104
}
112105

113106
public async wrapAttributes(
@@ -120,7 +113,7 @@ export class AttributeService<
120113
? (input as SavedObjectEmbeddableInput).savedObjectId
121114
: undefined;
122115
if (!useRefType) {
123-
return { [this.attributesKey]: newAttributes } as ValType;
116+
return { [ATTRIBUTE_SERVICE_KEY]: newAttributes } as ValType;
124117
} else {
125118
try {
126119
const originalInput = input ? input : {};
@@ -205,7 +198,7 @@ export class AttributeService<
205198
}
206199
);
207200
try {
208-
const newAttributes = { ...input[this.attributesKey] };
201+
const newAttributes = { ...input[ATTRIBUTE_SERVICE_KEY] };
209202
newAttributes.title = props.newTitle;
210203
const wrappedInput = (await this.wrapAttributes(newAttributes, true)) as RefType;
211204
resolve(wrappedInput);
@@ -221,7 +214,7 @@ export class AttributeService<
221214
<SavedObjectSaveModal
222215
onSave={onSave}
223216
onClose={() => reject()}
224-
title={embeddable.getTitle() || input[this.attributesKey].title}
217+
title={embeddable.getTitle() || input[ATTRIBUTE_SERVICE_KEY].title}
225218
showCopyOnSave={false}
226219
objectType={this.type}
227220
showDescription={false}

src/plugins/dashboard/public/attribute_service/attribute_service_mock.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,21 @@ import { EmbeddableInput, SavedObjectEmbeddableInput } from '../embeddable_plugi
2121
import { coreMock } from '../../../../core/public/mocks';
2222
import { AttributeServiceOptions } from './attribute_service';
2323
import { CoreStart } from '../../../../core/public';
24-
import { AttributeService, ATTRIBUTE_SERVICE_DEFAULT_KEY } from '..';
24+
import { AttributeService, ATTRIBUTE_SERVICE_KEY } from '..';
2525

2626
export const mockAttributeService = <
2727
A extends { title: string },
28-
K extends string = typeof ATTRIBUTE_SERVICE_DEFAULT_KEY,
29-
V extends EmbeddableInput & { [key in K]: A } = EmbeddableInput & { [key in K]: A },
28+
V extends EmbeddableInput & { [ATTRIBUTE_SERVICE_KEY]: A } = EmbeddableInput & {
29+
[ATTRIBUTE_SERVICE_KEY]: A;
30+
},
3031
R extends SavedObjectEmbeddableInput = SavedObjectEmbeddableInput
3132
>(
3233
type: string,
33-
options?: AttributeServiceOptions<A, K>,
34+
options?: AttributeServiceOptions<A>,
3435
customCore?: jest.Mocked<CoreStart>
35-
): AttributeService<A, K, V, R> => {
36+
): AttributeService<A, V, R> => {
3637
const core = customCore ? customCore : coreMock.createStart();
37-
const service = new AttributeService<A, K, V, R>(
38+
const service = new AttributeService<A, V, R>(
3839
type,
3940
jest.fn(),
4041
core.savedObjects.client,

src/plugins/dashboard/public/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ export {
4040
export { addEmbeddableToDashboardUrl } from './url_utils/url_helper';
4141
export { SavedObjectDashboard } from './saved_dashboards';
4242
export { SavedDashboardPanel } from './types';
43-
export {
44-
AttributeService,
45-
ATTRIBUTE_SERVICE_DEFAULT_KEY,
46-
} from './attribute_service/attribute_service';
43+
export { AttributeService, ATTRIBUTE_SERVICE_KEY } from './attribute_service/attribute_service';
4744

4845
export function plugin(initializerContext: PluginInitializerContext) {
4946
return new DashboardPlugin(initializerContext);

src/plugins/dashboard/public/plugin.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ import {
103103
} from './application/actions/add_to_library_action';
104104
import {
105105
AttributeServiceOptions,
106-
ATTRIBUTE_SERVICE_DEFAULT_KEY,
106+
ATTRIBUTE_SERVICE_KEY,
107107
} from './attribute_service/attribute_service';
108108

109109
declare module '../../share/public' {
@@ -153,13 +153,14 @@ export interface DashboardStart {
153153
DashboardContainerByValueRenderer: ReturnType<typeof createDashboardContainerByValueRenderer>;
154154
getAttributeService: <
155155
A extends { title: string },
156-
K extends string = typeof ATTRIBUTE_SERVICE_DEFAULT_KEY,
157-
V extends EmbeddableInput & { [key in K]: A } = EmbeddableInput & { [key in K]: A },
156+
V extends EmbeddableInput & { [ATTRIBUTE_SERVICE_KEY]: A } = EmbeddableInput & {
157+
[ATTRIBUTE_SERVICE_KEY]: A;
158+
},
158159
R extends SavedObjectEmbeddableInput = SavedObjectEmbeddableInput
159160
>(
160161
type: string,
161-
options?: AttributeServiceOptions<A, K>
162-
) => AttributeService<A, K, V, R>;
162+
options?: AttributeServiceOptions<A>
163+
) => AttributeService<A, V, R>;
163164
}
164165

165166
declare module '../../../plugins/ui_actions/public' {

0 commit comments

Comments
 (0)