Feat/edit labels on tasks (#11122)
* Replace EditDashboardLabelsOverlay with generic EditLabelsOverlay * Add ability to add/remove labels from a taskpull/11128/head
parent
fb42bf672c
commit
d9a3b6d76c
|
@ -3196,6 +3196,150 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
|
'/tasks/{taskID}/labels':
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Tasks
|
||||||
|
summary: list all labels for a task
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/TraceSpan'
|
||||||
|
- in: path
|
||||||
|
name: taskID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: ID of the task
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: a list of all labels for a task
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
labels:
|
||||||
|
$ref: "#/components/schemas/Labels"
|
||||||
|
links:
|
||||||
|
$ref: "#/components/schemas/Links"
|
||||||
|
default:
|
||||||
|
description: unexpected error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Tasks
|
||||||
|
summary: add a label to a task
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/TraceSpan'
|
||||||
|
- in: path
|
||||||
|
name: taskID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: ID of the task
|
||||||
|
requestBody:
|
||||||
|
description: label to add
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Label"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: a list of all labels for a task
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
labels:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
links:
|
||||||
|
$ref: "#/components/schemas/Links"
|
||||||
|
default:
|
||||||
|
description: unexpected error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
'/tasks/{taskID}/labels/{label}':
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- Tasks
|
||||||
|
summary: delete a label from a task
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/TraceSpan'
|
||||||
|
- in: path
|
||||||
|
name: taskID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: ID of the task
|
||||||
|
- in: path
|
||||||
|
name: label
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: the label name
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: delete has been accepted
|
||||||
|
'404':
|
||||||
|
description: task not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
default:
|
||||||
|
description: unexpected error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
patch:
|
||||||
|
tags:
|
||||||
|
- Tasks
|
||||||
|
summary: update a label from a task
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/TraceSpan'
|
||||||
|
- in: path
|
||||||
|
name: taskID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: ID of the task
|
||||||
|
- in: path
|
||||||
|
name: label
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: the label name
|
||||||
|
requestBody:
|
||||||
|
description: label update to apply
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/LabelRequest"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: updated successfully
|
||||||
|
'404':
|
||||||
|
description: task not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
default:
|
||||||
|
description: unexpected error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
/me:
|
/me:
|
||||||
get:
|
get:
|
||||||
x-generated: true
|
x-generated: true
|
||||||
|
@ -5947,4 +6091,15 @@ components:
|
||||||
type: object
|
type: object
|
||||||
description: Key/Value pairs associated with this label. Keys can be removed by sending an update with an empty value.
|
description: Key/Value pairs associated with this label. Keys can be removed by sending an update with an empty value.
|
||||||
example: {"color": "#ffb3b3", "description": "this is a description"}
|
example: {"color": "#ffb3b3", "description": "this is a description"}
|
||||||
|
LabelRequest:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
resourceID:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
properties:
|
||||||
|
type: object
|
||||||
|
description: Key/Value pairs associated with this label. Keys can be removed by sending an update with an empty value.
|
||||||
|
example: {"color": "#ffb3b3", "description": "this is a description"}
|
||||||
|
|
|
@ -1176,6 +1176,26 @@ export interface InlineResponse2004 {
|
||||||
links?: Links;
|
links?: Links;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface InlineResponse2005
|
||||||
|
*/
|
||||||
|
export interface InlineResponse2005 {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<string>}
|
||||||
|
* @memberof InlineResponse2005
|
||||||
|
*/
|
||||||
|
labels?: Array<string>;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Links}
|
||||||
|
* @memberof InlineResponse2005
|
||||||
|
*/
|
||||||
|
links?: Links;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -1216,6 +1236,32 @@ export interface Label {
|
||||||
properties?: any;
|
properties?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface LabelRequest
|
||||||
|
*/
|
||||||
|
export interface LabelRequest {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof LabelRequest
|
||||||
|
*/
|
||||||
|
resourceID?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof LabelRequest
|
||||||
|
*/
|
||||||
|
name?: string;
|
||||||
|
/**
|
||||||
|
* Key/Value pairs associated with this label. Keys can be removed by sending an update with an empty value.
|
||||||
|
* @type {any}
|
||||||
|
* @memberof LabelRequest
|
||||||
|
*/
|
||||||
|
properties?: any;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* flux query to be analyzed.
|
* flux query to be analyzed.
|
||||||
* @export
|
* @export
|
||||||
|
@ -12046,6 +12092,188 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
|
||||||
options: localVarRequestOptions,
|
options: localVarRequestOptions,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary list all labels for a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsGet(taskID: string, zapTraceSpan?: string, options: any = {}): RequestArgs {
|
||||||
|
// verify required parameter 'taskID' is not null or undefined
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new RequiredError('taskID','Required parameter taskID was null or undefined when calling tasksTaskIDLabelsGet.');
|
||||||
|
}
|
||||||
|
const localVarPath = `/tasks/{taskID}/labels`
|
||||||
|
.replace(`{${"taskID"}}`, encodeURIComponent(String(taskID)));
|
||||||
|
const localVarUrlObj = url.parse(localVarPath, true);
|
||||||
|
let baseOptions;
|
||||||
|
if (configuration) {
|
||||||
|
baseOptions = configuration.baseOptions;
|
||||||
|
}
|
||||||
|
const localVarRequestOptions = Object.assign({ method: 'GET' }, baseOptions, options);
|
||||||
|
const localVarHeaderParameter = {} as any;
|
||||||
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
if (zapTraceSpan !== undefined && zapTraceSpan !== null) {
|
||||||
|
localVarHeaderParameter['Zap-Trace-Span'] = String(zapTraceSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarUrlObj.query = Object.assign({}, localVarUrlObj.query, localVarQueryParameter, options.query);
|
||||||
|
// fix override query string Detail: https://stackoverflow.com/a/7517673/1077943
|
||||||
|
delete localVarUrlObj.search;
|
||||||
|
localVarRequestOptions.headers = Object.assign({}, localVarHeaderParameter, options.headers);
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: url.format(localVarUrlObj),
|
||||||
|
options: localVarRequestOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary delete a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsLabelDelete(taskID: string, label: string, zapTraceSpan?: string, options: any = {}): RequestArgs {
|
||||||
|
// verify required parameter 'taskID' is not null or undefined
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new RequiredError('taskID','Required parameter taskID was null or undefined when calling tasksTaskIDLabelsLabelDelete.');
|
||||||
|
}
|
||||||
|
// verify required parameter 'label' is not null or undefined
|
||||||
|
if (label === null || label === undefined) {
|
||||||
|
throw new RequiredError('label','Required parameter label was null or undefined when calling tasksTaskIDLabelsLabelDelete.');
|
||||||
|
}
|
||||||
|
const localVarPath = `/tasks/{taskID}/labels/{label}`
|
||||||
|
.replace(`{${"taskID"}}`, encodeURIComponent(String(taskID)))
|
||||||
|
.replace(`{${"label"}}`, encodeURIComponent(String(label)));
|
||||||
|
const localVarUrlObj = url.parse(localVarPath, true);
|
||||||
|
let baseOptions;
|
||||||
|
if (configuration) {
|
||||||
|
baseOptions = configuration.baseOptions;
|
||||||
|
}
|
||||||
|
const localVarRequestOptions = Object.assign({ method: 'DELETE' }, baseOptions, options);
|
||||||
|
const localVarHeaderParameter = {} as any;
|
||||||
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
if (zapTraceSpan !== undefined && zapTraceSpan !== null) {
|
||||||
|
localVarHeaderParameter['Zap-Trace-Span'] = String(zapTraceSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarUrlObj.query = Object.assign({}, localVarUrlObj.query, localVarQueryParameter, options.query);
|
||||||
|
// fix override query string Detail: https://stackoverflow.com/a/7517673/1077943
|
||||||
|
delete localVarUrlObj.search;
|
||||||
|
localVarRequestOptions.headers = Object.assign({}, localVarHeaderParameter, options.headers);
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: url.format(localVarUrlObj),
|
||||||
|
options: localVarRequestOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary update a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {LabelRequest} labelRequest label update to apply
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsLabelPatch(taskID: string, label: string, labelRequest: LabelRequest, zapTraceSpan?: string, options: any = {}): RequestArgs {
|
||||||
|
// verify required parameter 'taskID' is not null or undefined
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new RequiredError('taskID','Required parameter taskID was null or undefined when calling tasksTaskIDLabelsLabelPatch.');
|
||||||
|
}
|
||||||
|
// verify required parameter 'label' is not null or undefined
|
||||||
|
if (label === null || label === undefined) {
|
||||||
|
throw new RequiredError('label','Required parameter label was null or undefined when calling tasksTaskIDLabelsLabelPatch.');
|
||||||
|
}
|
||||||
|
// verify required parameter 'labelRequest' is not null or undefined
|
||||||
|
if (labelRequest === null || labelRequest === undefined) {
|
||||||
|
throw new RequiredError('labelRequest','Required parameter labelRequest was null or undefined when calling tasksTaskIDLabelsLabelPatch.');
|
||||||
|
}
|
||||||
|
const localVarPath = `/tasks/{taskID}/labels/{label}`
|
||||||
|
.replace(`{${"taskID"}}`, encodeURIComponent(String(taskID)))
|
||||||
|
.replace(`{${"label"}}`, encodeURIComponent(String(label)));
|
||||||
|
const localVarUrlObj = url.parse(localVarPath, true);
|
||||||
|
let baseOptions;
|
||||||
|
if (configuration) {
|
||||||
|
baseOptions = configuration.baseOptions;
|
||||||
|
}
|
||||||
|
const localVarRequestOptions = Object.assign({ method: 'PATCH' }, baseOptions, options);
|
||||||
|
const localVarHeaderParameter = {} as any;
|
||||||
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
if (zapTraceSpan !== undefined && zapTraceSpan !== null) {
|
||||||
|
localVarHeaderParameter['Zap-Trace-Span'] = String(zapTraceSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||||
|
|
||||||
|
localVarUrlObj.query = Object.assign({}, localVarUrlObj.query, localVarQueryParameter, options.query);
|
||||||
|
// fix override query string Detail: https://stackoverflow.com/a/7517673/1077943
|
||||||
|
delete localVarUrlObj.search;
|
||||||
|
localVarRequestOptions.headers = Object.assign({}, localVarHeaderParameter, options.headers);
|
||||||
|
const needsSerialization = (<any>"LabelRequest" !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
|
||||||
|
localVarRequestOptions.data = needsSerialization ? JSON.stringify(labelRequest || {}) : (labelRequest || "");
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: url.format(localVarUrlObj),
|
||||||
|
options: localVarRequestOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary add a label to a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {Label} label label to add
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsPost(taskID: string, label: Label, zapTraceSpan?: string, options: any = {}): RequestArgs {
|
||||||
|
// verify required parameter 'taskID' is not null or undefined
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new RequiredError('taskID','Required parameter taskID was null or undefined when calling tasksTaskIDLabelsPost.');
|
||||||
|
}
|
||||||
|
// verify required parameter 'label' is not null or undefined
|
||||||
|
if (label === null || label === undefined) {
|
||||||
|
throw new RequiredError('label','Required parameter label was null or undefined when calling tasksTaskIDLabelsPost.');
|
||||||
|
}
|
||||||
|
const localVarPath = `/tasks/{taskID}/labels`
|
||||||
|
.replace(`{${"taskID"}}`, encodeURIComponent(String(taskID)));
|
||||||
|
const localVarUrlObj = url.parse(localVarPath, true);
|
||||||
|
let baseOptions;
|
||||||
|
if (configuration) {
|
||||||
|
baseOptions = configuration.baseOptions;
|
||||||
|
}
|
||||||
|
const localVarRequestOptions = Object.assign({ method: 'POST' }, baseOptions, options);
|
||||||
|
const localVarHeaderParameter = {} as any;
|
||||||
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
if (zapTraceSpan !== undefined && zapTraceSpan !== null) {
|
||||||
|
localVarHeaderParameter['Zap-Trace-Span'] = String(zapTraceSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||||
|
|
||||||
|
localVarUrlObj.query = Object.assign({}, localVarUrlObj.query, localVarQueryParameter, options.query);
|
||||||
|
// fix override query string Detail: https://stackoverflow.com/a/7517673/1077943
|
||||||
|
delete localVarUrlObj.search;
|
||||||
|
localVarRequestOptions.headers = Object.assign({}, localVarHeaderParameter, options.headers);
|
||||||
|
const needsSerialization = (<any>"Label" !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
|
||||||
|
localVarRequestOptions.data = needsSerialization ? JSON.stringify(label || {}) : (label || "");
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: url.format(localVarUrlObj),
|
||||||
|
options: localVarRequestOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary Retrieve all logs for a task
|
* @summary Retrieve all logs for a task
|
||||||
|
@ -12586,6 +12814,70 @@ export const TasksApiFp = function(configuration?: Configuration) {
|
||||||
return axios.request(axiosRequestArgs);
|
return axios.request(axiosRequestArgs);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary list all labels for a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsGet(taskID: string, zapTraceSpan?: string, options?: any): (axios?: AxiosInstance, basePath?: string) => AxiosPromise<InlineResponse200> {
|
||||||
|
const localVarAxiosArgs = TasksApiAxiosParamCreator(configuration).tasksTaskIDLabelsGet(taskID, zapTraceSpan, options);
|
||||||
|
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||||
|
const axiosRequestArgs = Object.assign(localVarAxiosArgs.options, {url: basePath + localVarAxiosArgs.url})
|
||||||
|
return axios.request(axiosRequestArgs);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary delete a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsLabelDelete(taskID: string, label: string, zapTraceSpan?: string, options?: any): (axios?: AxiosInstance, basePath?: string) => AxiosPromise<Response> {
|
||||||
|
const localVarAxiosArgs = TasksApiAxiosParamCreator(configuration).tasksTaskIDLabelsLabelDelete(taskID, label, zapTraceSpan, options);
|
||||||
|
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||||
|
const axiosRequestArgs = Object.assign(localVarAxiosArgs.options, {url: basePath + localVarAxiosArgs.url})
|
||||||
|
return axios.request(axiosRequestArgs);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary update a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {LabelRequest} labelRequest label update to apply
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsLabelPatch(taskID: string, label: string, labelRequest: LabelRequest, zapTraceSpan?: string, options?: any): (axios?: AxiosInstance, basePath?: string) => AxiosPromise<Response> {
|
||||||
|
const localVarAxiosArgs = TasksApiAxiosParamCreator(configuration).tasksTaskIDLabelsLabelPatch(taskID, label, labelRequest, zapTraceSpan, options);
|
||||||
|
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||||
|
const axiosRequestArgs = Object.assign(localVarAxiosArgs.options, {url: basePath + localVarAxiosArgs.url})
|
||||||
|
return axios.request(axiosRequestArgs);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary add a label to a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {Label} label label to add
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsPost(taskID: string, label: Label, zapTraceSpan?: string, options?: any): (axios?: AxiosInstance, basePath?: string) => AxiosPromise<InlineResponse2005> {
|
||||||
|
const localVarAxiosArgs = TasksApiAxiosParamCreator(configuration).tasksTaskIDLabelsPost(taskID, label, zapTraceSpan, options);
|
||||||
|
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||||
|
const axiosRequestArgs = Object.assign(localVarAxiosArgs.options, {url: basePath + localVarAxiosArgs.url})
|
||||||
|
return axios.request(axiosRequestArgs);
|
||||||
|
};
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary Retrieve all logs for a task
|
* @summary Retrieve all logs for a task
|
||||||
|
@ -12817,6 +13109,54 @@ export const TasksApiFactory = function (configuration?: Configuration, basePath
|
||||||
tasksTaskIDGet(taskID: string, options?: any) {
|
tasksTaskIDGet(taskID: string, options?: any) {
|
||||||
return TasksApiFp(configuration).tasksTaskIDGet(taskID, options)(axios, basePath);
|
return TasksApiFp(configuration).tasksTaskIDGet(taskID, options)(axios, basePath);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary list all labels for a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsGet(taskID: string, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(configuration).tasksTaskIDLabelsGet(taskID, zapTraceSpan, options)(axios, basePath);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary delete a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsLabelDelete(taskID: string, label: string, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(configuration).tasksTaskIDLabelsLabelDelete(taskID, label, zapTraceSpan, options)(axios, basePath);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary update a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {LabelRequest} labelRequest label update to apply
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsLabelPatch(taskID: string, label: string, labelRequest: LabelRequest, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(configuration).tasksTaskIDLabelsLabelPatch(taskID, label, labelRequest, zapTraceSpan, options)(axios, basePath);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary add a label to a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {Label} label label to add
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
tasksTaskIDLabelsPost(taskID: string, label: Label, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(configuration).tasksTaskIDLabelsPost(taskID, label, zapTraceSpan, options)(axios, basePath);
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary Retrieve all logs for a task
|
* @summary Retrieve all logs for a task
|
||||||
|
@ -13009,6 +13349,62 @@ export class TasksApi extends BaseAPI {
|
||||||
return TasksApiFp(this.configuration).tasksTaskIDGet(taskID, options)(this.axios, this.basePath);
|
return TasksApiFp(this.configuration).tasksTaskIDGet(taskID, options)(this.axios, this.basePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary list all labels for a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
* @memberof TasksApi
|
||||||
|
*/
|
||||||
|
public tasksTaskIDLabelsGet(taskID: string, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(this.configuration).tasksTaskIDLabelsGet(taskID, zapTraceSpan, options)(this.axios, this.basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary delete a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
* @memberof TasksApi
|
||||||
|
*/
|
||||||
|
public tasksTaskIDLabelsLabelDelete(taskID: string, label: string, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(this.configuration).tasksTaskIDLabelsLabelDelete(taskID, label, zapTraceSpan, options)(this.axios, this.basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary update a label from a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {string} label the label name
|
||||||
|
* @param {LabelRequest} labelRequest label update to apply
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
* @memberof TasksApi
|
||||||
|
*/
|
||||||
|
public tasksTaskIDLabelsLabelPatch(taskID: string, label: string, labelRequest: LabelRequest, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(this.configuration).tasksTaskIDLabelsLabelPatch(taskID, label, labelRequest, zapTraceSpan, options)(this.axios, this.basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary add a label to a task
|
||||||
|
* @param {string} taskID ID of the task
|
||||||
|
* @param {Label} label label to add
|
||||||
|
* @param {string} [zapTraceSpan] OpenTracing span context
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
* @memberof TasksApi
|
||||||
|
*/
|
||||||
|
public tasksTaskIDLabelsPost(taskID: string, label: Label, zapTraceSpan?: string, options?: any) {
|
||||||
|
return TasksApiFp(this.configuration).tasksTaskIDLabelsPost(taskID, label, zapTraceSpan, options)(this.axios, this.basePath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary Retrieve all logs for a task
|
* @summary Retrieve all logs for a task
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
IconFont,
|
IconFont,
|
||||||
} from 'src/clockface'
|
} from 'src/clockface'
|
||||||
import ImportDashboardOverlay from 'src/dashboards/components/ImportDashboardOverlay'
|
import ImportDashboardOverlay from 'src/dashboards/components/ImportDashboardOverlay'
|
||||||
import EditDashboardLabelsOverlay from 'src/dashboards/components/EditDashboardLabelsOverlay'
|
import EditLabelsOverlay from 'src/shared/components/EditLabelsOverlay'
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import {getDeep} from 'src/utils/wrappers'
|
import {getDeep} from 'src/utils/wrappers'
|
||||||
|
@ -288,11 +288,11 @@ class DashboardIndex extends PureComponent<Props, State> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OverlayTechnology visible={isEditingDashboardLabels}>
|
<OverlayTechnology visible={isEditingDashboardLabels}>
|
||||||
<EditDashboardLabelsOverlay
|
<EditLabelsOverlay<Dashboard>
|
||||||
dashboard={dashboardLabelsEdit}
|
resource={dashboardLabelsEdit}
|
||||||
onDismissOverlay={this.handleStopEditingLabels}
|
onDismissOverlay={this.handleStopEditingLabels}
|
||||||
onAddDashboardLabels={onAddDashboardLabels}
|
onAddLabels={onAddDashboardLabels}
|
||||||
onRemoveDashboardLabels={onRemoveDashboardLabels}
|
onRemoveLabels={onRemoveDashboardLabels}
|
||||||
/>
|
/>
|
||||||
</OverlayTechnology>
|
</OverlayTechnology>
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,25 +17,21 @@ import {
|
||||||
} from 'src/clockface'
|
} from 'src/clockface'
|
||||||
import FetchLabels from 'src/shared/components/FetchLabels'
|
import FetchLabels from 'src/shared/components/FetchLabels'
|
||||||
|
|
||||||
// Actions
|
|
||||||
import {
|
|
||||||
addDashboardLabelsAsync,
|
|
||||||
removeDashboardLabelsAsync,
|
|
||||||
} from 'src/dashboards/actions/v2'
|
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {Dashboard} from 'src/types/v2'
|
|
||||||
import {Label} from 'src/api'
|
import {Label} from 'src/api'
|
||||||
import {RemoteDataState} from 'src/types'
|
import {RemoteDataState} from 'src/types'
|
||||||
|
|
||||||
interface Props {
|
// Utils
|
||||||
dashboard: Dashboard
|
import {getDeep} from 'src/utils/wrappers'
|
||||||
|
|
||||||
|
interface Props<T> {
|
||||||
|
resource: T
|
||||||
onDismissOverlay: () => void
|
onDismissOverlay: () => void
|
||||||
onAddDashboardLabels: typeof addDashboardLabelsAsync
|
onAddLabels: (resourceID: string, labels: Label[]) => void
|
||||||
onRemoveDashboardLabels: typeof removeDashboardLabelsAsync
|
onRemoveLabels: (resourceID: string, labels: Label[]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
@ -44,18 +40,18 @@ interface State {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ErrorHandling
|
@ErrorHandling
|
||||||
class EditDashboardLabelsOverlay extends PureComponent<Props, State> {
|
class EditLabelsOverlay<T> extends PureComponent<Props<T>, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props<T>) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
selectedLabels: props.dashboard.labels,
|
selectedLabels: _.get(props, 'resource.labels'),
|
||||||
loading: RemoteDataState.NotStarted,
|
loading: RemoteDataState.NotStarted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {onDismissOverlay, dashboard} = this.props
|
const {onDismissOverlay, resource} = this.props
|
||||||
const {selectedLabels} = this.state
|
const {selectedLabels} = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -73,7 +69,7 @@ class EditDashboardLabelsOverlay extends PureComponent<Props, State> {
|
||||||
<LabelSelector
|
<LabelSelector
|
||||||
inputSize={ComponentSize.Medium}
|
inputSize={ComponentSize.Medium}
|
||||||
allLabels={labels}
|
allLabels={labels}
|
||||||
resourceType={dashboard.name}
|
resourceType={_.get(resource, 'name')}
|
||||||
selectedLabels={selectedLabels}
|
selectedLabels={selectedLabels}
|
||||||
onAddLabel={this.handleAddLabel}
|
onAddLabel={this.handleAddLabel}
|
||||||
onRemoveLabel={this.handleRemoveLabel}
|
onRemoveLabel={this.handleRemoveLabel}
|
||||||
|
@ -118,15 +114,12 @@ class EditDashboardLabelsOverlay extends PureComponent<Props, State> {
|
||||||
removedLabels: Label[]
|
removedLabels: Label[]
|
||||||
addedLabels: Label[]
|
addedLabels: Label[]
|
||||||
} {
|
} {
|
||||||
const {dashboard} = this.props
|
const {resource} = this.props
|
||||||
const {selectedLabels} = this.state
|
const {selectedLabels} = this.state
|
||||||
|
const labels = getDeep<Label[]>(resource, 'labels', [])
|
||||||
|
|
||||||
const intersection = _.intersectionBy(
|
const intersection = _.intersectionBy(labels, selectedLabels, 'name')
|
||||||
dashboard.labels,
|
const removedLabels = _.differenceBy(labels, intersection, 'name')
|
||||||
selectedLabels,
|
|
||||||
'name'
|
|
||||||
)
|
|
||||||
const removedLabels = _.differenceBy(dashboard.labels, intersection, 'name')
|
|
||||||
const addedLabels = _.differenceBy(selectedLabels, intersection, 'name')
|
const addedLabels = _.differenceBy(selectedLabels, intersection, 'name')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -155,23 +148,19 @@ class EditDashboardLabelsOverlay extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSaveLabels = async (): Promise<void> => {
|
private handleSaveLabels = async (): Promise<void> => {
|
||||||
const {
|
const {onAddLabels, onRemoveLabels, resource, onDismissOverlay} = this.props
|
||||||
onAddDashboardLabels,
|
|
||||||
onRemoveDashboardLabels,
|
|
||||||
dashboard,
|
|
||||||
onDismissOverlay,
|
|
||||||
} = this.props
|
|
||||||
|
|
||||||
const {addedLabels, removedLabels} = this.changes
|
const {addedLabels, removedLabels} = this.changes
|
||||||
|
const resourceID = _.get(resource, 'id')
|
||||||
|
|
||||||
this.setState({loading: RemoteDataState.Loading})
|
this.setState({loading: RemoteDataState.Loading})
|
||||||
|
|
||||||
if (addedLabels.length) {
|
if (addedLabels.length) {
|
||||||
await onAddDashboardLabels(dashboard.id, addedLabels)
|
await onAddLabels(resourceID, addedLabels)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removedLabels.length) {
|
if (removedLabels.length) {
|
||||||
await onRemoveDashboardLabels(dashboard.id, removedLabels)
|
await onRemoveLabels(resourceID, removedLabels)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({loading: RemoteDataState.Done})
|
this.setState({loading: RemoteDataState.Done})
|
||||||
|
@ -180,4 +169,4 @@ class EditDashboardLabelsOverlay extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EditDashboardLabelsOverlay
|
export default EditLabelsOverlay
|
|
@ -1,7 +1,8 @@
|
||||||
import {AppState} from 'src/types/v2'
|
// Libraries
|
||||||
import {push} from 'react-router-redux'
|
import {push} from 'react-router-redux'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
// APIs
|
||||||
import {Task as TaskAPI, Organization} from 'src/api'
|
import {Task as TaskAPI, Organization} from 'src/api'
|
||||||
import {
|
import {
|
||||||
submitNewTask,
|
submitNewTask,
|
||||||
|
@ -10,6 +11,8 @@ import {
|
||||||
getTask,
|
getTask,
|
||||||
updateTaskStatus as updateTaskStatusAPI,
|
updateTaskStatus as updateTaskStatusAPI,
|
||||||
deleteTask as deleteTaskAPI,
|
deleteTask as deleteTaskAPI,
|
||||||
|
addTaskLabels as addTaskLabelsAPI,
|
||||||
|
removeTaskLabels as removeTaskLabelsAPI,
|
||||||
} from 'src/tasks/api/v2'
|
} from 'src/tasks/api/v2'
|
||||||
import {getMe} from 'src/shared/apis/v2/user'
|
import {getMe} from 'src/shared/apis/v2/user'
|
||||||
import {notify} from 'src/shared/actions/notifications'
|
import {notify} from 'src/shared/actions/notifications'
|
||||||
|
@ -22,8 +25,13 @@ import {
|
||||||
taskImportFailed,
|
taskImportFailed,
|
||||||
taskImportSuccess,
|
taskImportSuccess,
|
||||||
} from 'src/shared/copy/v2/notifications'
|
} from 'src/shared/copy/v2/notifications'
|
||||||
import {getDeep} from 'src/utils/wrappers'
|
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import {AppState} from 'src/types/v2'
|
||||||
|
import {Label} from 'src/api'
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
import {getDeep} from 'src/utils/wrappers'
|
||||||
import {
|
import {
|
||||||
taskOptionsToFluxScript,
|
taskOptionsToFluxScript,
|
||||||
TaskOptionKeys,
|
TaskOptionKeys,
|
||||||
|
@ -42,6 +50,8 @@ export type Action =
|
||||||
| ClearTask
|
| ClearTask
|
||||||
| SetTaskOption
|
| SetTaskOption
|
||||||
| SetAllTaskOptions
|
| SetAllTaskOptions
|
||||||
|
| AddTaskLabels
|
||||||
|
| RemoveTaskLabels
|
||||||
|
|
||||||
type GetStateFunc = () => AppState
|
type GetStateFunc = () => AppState
|
||||||
interface Task extends TaskAPI {
|
interface Task extends TaskAPI {
|
||||||
|
@ -124,6 +134,22 @@ export interface SetTaskOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AddTaskLabels {
|
||||||
|
type: 'ADD_TASK_LABELS'
|
||||||
|
payload: {
|
||||||
|
taskID: string
|
||||||
|
labels: Label[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoveTaskLabels {
|
||||||
|
type: 'REMOVE_TASK_LABELS'
|
||||||
|
payload: {
|
||||||
|
taskID: string
|
||||||
|
labels: Label[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const setTaskOption = (taskOption: {
|
export const setTaskOption = (taskOption: {
|
||||||
key: TaskOptionKeys
|
key: TaskOptionKeys
|
||||||
value: string
|
value: string
|
||||||
|
@ -176,6 +202,27 @@ export const setDropdownOrgID = (dropdownOrgID: string): SetDropdownOrgID => ({
|
||||||
payload: {dropdownOrgID},
|
payload: {dropdownOrgID},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const addTaskLabels = (taskID: string, labels: Label[]): AddTaskLabels => ({
|
||||||
|
type: 'ADD_TASK_LABELS',
|
||||||
|
payload: {
|
||||||
|
taskID,
|
||||||
|
labels,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const removeTaskLabels = (
|
||||||
|
taskID: string,
|
||||||
|
labels: Label[]
|
||||||
|
): RemoveTaskLabels => ({
|
||||||
|
type: 'REMOVE_TASK_LABELS',
|
||||||
|
payload: {
|
||||||
|
taskID,
|
||||||
|
labels,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Thunks
|
||||||
|
|
||||||
export const updateTaskStatus = (task: Task) => async dispatch => {
|
export const updateTaskStatus = (task: Task) => async dispatch => {
|
||||||
try {
|
try {
|
||||||
await updateTaskStatusAPI(task.id, task.status)
|
await updateTaskStatusAPI(task.id, task.status)
|
||||||
|
@ -337,3 +384,42 @@ export const importScript = (script: string, fileName: string) => async (
|
||||||
dispatch(notify(taskImportFailed(fileName, message)))
|
dispatch(notify(taskImportFailed(fileName, message)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addTaskLabelsAsync = (taskID: string, labels: Label[]) => async (
|
||||||
|
dispatch,
|
||||||
|
getState: GetStateFunc
|
||||||
|
): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
tasks: {tasks},
|
||||||
|
} = await getState()
|
||||||
|
|
||||||
|
const task = tasks.find(t => {
|
||||||
|
return t.id === taskID
|
||||||
|
})
|
||||||
|
|
||||||
|
const labelsToAdd = labels.filter(label => {
|
||||||
|
if (!task.labels.find(l => l.name === label.name)) {
|
||||||
|
return label
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const newLabels = await addTaskLabelsAPI(taskID, labelsToAdd)
|
||||||
|
|
||||||
|
dispatch(addTaskLabels(taskID, newLabels))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removeTaskLabelsAsync = (
|
||||||
|
taskID: string,
|
||||||
|
labels: Label[]
|
||||||
|
) => async (dispatch): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await removeTaskLabelsAPI(taskID, labels)
|
||||||
|
dispatch(removeTaskLabels(taskID, labels))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import {Task} from 'src/api'
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
import {Task, Label} from 'src/api'
|
||||||
import {taskAPI} from 'src/utils/api'
|
import {taskAPI} from 'src/utils/api'
|
||||||
|
|
||||||
export const submitNewTask = async (
|
export const submitNewTask = async (
|
||||||
|
@ -41,3 +43,30 @@ export const getTask = async (id): Promise<Task> => {
|
||||||
export const deleteTask = (taskID: string) => {
|
export const deleteTask = (taskID: string) => {
|
||||||
return taskAPI.tasksTaskIDDelete(taskID)
|
return taskAPI.tasksTaskIDDelete(taskID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addTaskLabels = async (
|
||||||
|
taskID: string,
|
||||||
|
labels: Label[]
|
||||||
|
): Promise<Label[]> => {
|
||||||
|
await Promise.all(
|
||||||
|
labels.map(async label => {
|
||||||
|
await taskAPI.tasksTaskIDLabelsPost(taskID, label)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const {data} = await taskAPI.tasksTaskIDLabelsGet(taskID)
|
||||||
|
|
||||||
|
return data.labels
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removeTaskLabels = async (
|
||||||
|
taskID: string,
|
||||||
|
labels: Label[]
|
||||||
|
): Promise<void> => {
|
||||||
|
await Promise.all(
|
||||||
|
labels.map(async label => {
|
||||||
|
const name = _.get(label, 'name', '')
|
||||||
|
await taskAPI.tasksTaskIDLabelsLabelDelete(taskID, name)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ const setup = (override = {}) => {
|
||||||
onActivate: jest.fn(),
|
onActivate: jest.fn(),
|
||||||
onDelete: jest.fn(),
|
onDelete: jest.fn(),
|
||||||
onSelect: jest.fn(),
|
onSelect: jest.fn(),
|
||||||
|
onEditLabels: jest.fn(),
|
||||||
...override,
|
...override,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ interface Props {
|
||||||
onActivate: (task: Task) => void
|
onActivate: (task: Task) => void
|
||||||
onDelete: (task: Task) => void
|
onDelete: (task: Task) => void
|
||||||
onSelect: (task: Task) => void
|
onSelect: (task: Task) => void
|
||||||
|
onEditLabels: (task: Task) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TaskRow extends PureComponent<Props & WithRouterProps> {
|
export class TaskRow extends PureComponent<Props & WithRouterProps> {
|
||||||
|
@ -99,15 +100,26 @@ export class TaskRow extends PureComponent<Props & WithRouterProps> {
|
||||||
|
|
||||||
private get labels(): JSX.Element {
|
private get labels(): JSX.Element {
|
||||||
const {task} = this.props
|
const {task} = this.props
|
||||||
|
|
||||||
if (!task.labels.length) {
|
if (!task.labels.length) {
|
||||||
return
|
return (
|
||||||
|
<Label.Container
|
||||||
|
limitChildCount={4}
|
||||||
|
className="index-list--labels"
|
||||||
|
onEdit={this.handleEditLabels}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Label.Container limitChildCount={4} resourceName="this Task">
|
<Label.Container
|
||||||
|
limitChildCount={4}
|
||||||
|
resourceName="this Task"
|
||||||
|
onEdit={this.handleEditLabels}
|
||||||
|
>
|
||||||
{task.labels.map(label => (
|
{task.labels.map(label => (
|
||||||
<Label
|
<Label
|
||||||
key={label.resourceID}
|
key={label.name}
|
||||||
id={label.resourceID}
|
id={label.resourceID}
|
||||||
colorHex={label.properties.color}
|
colorHex={label.properties.color}
|
||||||
name={label.name}
|
name={label.name}
|
||||||
|
@ -126,6 +138,12 @@ export class TaskRow extends PureComponent<Props & WithRouterProps> {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleEditLabels = () => {
|
||||||
|
const {task, onEditLabels} = this.props
|
||||||
|
|
||||||
|
onEditLabels(task)
|
||||||
|
}
|
||||||
|
|
||||||
private changeToggle = () => {
|
private changeToggle = () => {
|
||||||
const {task, onActivate} = this.props
|
const {task, onActivate} = this.props
|
||||||
if (task.status === TaskAPI.StatusEnum.Active) {
|
if (task.status === TaskAPI.StatusEnum.Active) {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import _ from 'lodash'
|
||||||
import {IndexList} from 'src/clockface'
|
import {IndexList} from 'src/clockface'
|
||||||
import TaskRow from 'src/tasks/components/TaskRow'
|
import TaskRow from 'src/tasks/components/TaskRow'
|
||||||
import SortingHat from 'src/shared/components/sorting_hat/SortingHat'
|
import SortingHat from 'src/shared/components/sorting_hat/SortingHat'
|
||||||
|
import {OverlayTechnology} from 'src/clockface'
|
||||||
|
import EditLabelsOverlay from 'src/shared/components/EditLabelsOverlay'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import EmptyTasksList from 'src/tasks/components/EmptyTasksList'
|
import EmptyTasksList from 'src/tasks/components/EmptyTasksList'
|
||||||
|
@ -16,6 +18,7 @@ interface Task extends TaskAPI {
|
||||||
owner?: User
|
owner?: User
|
||||||
}
|
}
|
||||||
import {Sort} from 'src/clockface'
|
import {Sort} from 'src/clockface'
|
||||||
|
import {addTaskLabelsAsync, removeTaskLabelsAsync} from 'src/tasks/actions/v2'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
tasks: Task[]
|
tasks: Task[]
|
||||||
|
@ -25,6 +28,8 @@ interface Props {
|
||||||
onCreate: () => void
|
onCreate: () => void
|
||||||
onSelect: (task: Task) => void
|
onSelect: (task: Task) => void
|
||||||
totalCount: number
|
totalCount: number
|
||||||
|
onRemoveTaskLabels: typeof removeTaskLabelsAsync
|
||||||
|
onAddTaskLabels: typeof addTaskLabelsAsync
|
||||||
}
|
}
|
||||||
|
|
||||||
type SortKey = keyof Task | 'organization.name'
|
type SortKey = keyof Task | 'organization.name'
|
||||||
|
@ -32,6 +37,8 @@ type SortKey = keyof Task | 'organization.name'
|
||||||
interface State {
|
interface State {
|
||||||
sortKey: SortKey
|
sortKey: SortKey
|
||||||
sortDirection: Sort
|
sortDirection: Sort
|
||||||
|
taskLabelsEdit: Task
|
||||||
|
isEditingTaskLabels: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TasksList extends PureComponent<Props, State> {
|
export default class TasksList extends PureComponent<Props, State> {
|
||||||
|
@ -40,6 +47,8 @@ export default class TasksList extends PureComponent<Props, State> {
|
||||||
this.state = {
|
this.state = {
|
||||||
sortKey: null,
|
sortKey: null,
|
||||||
sortDirection: Sort.Descending,
|
sortDirection: Sort.Descending,
|
||||||
|
taskLabelsEdit: null,
|
||||||
|
isEditingTaskLabels: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,51 +64,54 @@ export default class TasksList extends PureComponent<Props, State> {
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IndexList>
|
<>
|
||||||
<IndexList.Header>
|
<IndexList>
|
||||||
<IndexList.HeaderCell
|
<IndexList.Header>
|
||||||
columnName="Name"
|
<IndexList.HeaderCell
|
||||||
width="20%"
|
columnName="Name"
|
||||||
sortKey={headerKeys[0]}
|
width="20%"
|
||||||
sort={sortKey === headerKeys[0] ? sortDirection : Sort.None}
|
sortKey={headerKeys[0]}
|
||||||
onClick={this.handleClickColumn}
|
sort={sortKey === headerKeys[0] ? sortDirection : Sort.None}
|
||||||
/>
|
onClick={this.handleClickColumn}
|
||||||
<IndexList.HeaderCell
|
|
||||||
columnName="Active"
|
|
||||||
width="10%"
|
|
||||||
sortKey={headerKeys[1]}
|
|
||||||
sort={sortKey === headerKeys[1] ? sortDirection : Sort.None}
|
|
||||||
onClick={this.handleClickColumn}
|
|
||||||
/>
|
|
||||||
<IndexList.HeaderCell
|
|
||||||
columnName="Schedule"
|
|
||||||
width="20%"
|
|
||||||
sortKey={headerKeys[2]}
|
|
||||||
sort={sortKey === headerKeys[2] ? sortDirection : Sort.None}
|
|
||||||
onClick={this.handleClickColumn}
|
|
||||||
/>
|
|
||||||
<IndexList.HeaderCell
|
|
||||||
columnName="Owner"
|
|
||||||
width="15%"
|
|
||||||
sortKey={headerKeys[3]}
|
|
||||||
sort={sortKey === headerKeys[3] ? sortDirection : Sort.None}
|
|
||||||
onClick={this.handleClickColumn}
|
|
||||||
/>
|
|
||||||
<IndexList.HeaderCell columnName="" width="35%" />
|
|
||||||
</IndexList.Header>
|
|
||||||
<IndexList.Body
|
|
||||||
emptyState={
|
|
||||||
<EmptyTasksList
|
|
||||||
searchTerm={searchTerm}
|
|
||||||
onCreate={onCreate}
|
|
||||||
totalCount={totalCount}
|
|
||||||
/>
|
/>
|
||||||
}
|
<IndexList.HeaderCell
|
||||||
columnCount={5}
|
columnName="Active"
|
||||||
>
|
width="10%"
|
||||||
{this.sortedRows}
|
sortKey={headerKeys[1]}
|
||||||
</IndexList.Body>
|
sort={sortKey === headerKeys[1] ? sortDirection : Sort.None}
|
||||||
</IndexList>
|
onClick={this.handleClickColumn}
|
||||||
|
/>
|
||||||
|
<IndexList.HeaderCell
|
||||||
|
columnName="Schedule"
|
||||||
|
width="20%"
|
||||||
|
sortKey={headerKeys[2]}
|
||||||
|
sort={sortKey === headerKeys[2] ? sortDirection : Sort.None}
|
||||||
|
onClick={this.handleClickColumn}
|
||||||
|
/>
|
||||||
|
<IndexList.HeaderCell
|
||||||
|
columnName="Owner"
|
||||||
|
width="15%"
|
||||||
|
sortKey={headerKeys[3]}
|
||||||
|
sort={sortKey === headerKeys[3] ? sortDirection : Sort.None}
|
||||||
|
onClick={this.handleClickColumn}
|
||||||
|
/>
|
||||||
|
<IndexList.HeaderCell columnName="" width="35%" />
|
||||||
|
</IndexList.Header>
|
||||||
|
<IndexList.Body
|
||||||
|
emptyState={
|
||||||
|
<EmptyTasksList
|
||||||
|
searchTerm={searchTerm}
|
||||||
|
onCreate={onCreate}
|
||||||
|
totalCount={totalCount}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
columnCount={5}
|
||||||
|
>
|
||||||
|
{this.sortedRows}
|
||||||
|
</IndexList.Body>
|
||||||
|
</IndexList>
|
||||||
|
{this.renderLabelEditorOverlay}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +130,7 @@ export default class TasksList extends PureComponent<Props, State> {
|
||||||
onActivate={onActivate}
|
onActivate={onActivate}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
|
onEditLabels={this.handleStartEditingLabels}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
@ -143,4 +156,28 @@ export default class TasksList extends PureComponent<Props, State> {
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleStartEditingLabels = (taskLabelsEdit: Task): void => {
|
||||||
|
this.setState({taskLabelsEdit, isEditingTaskLabels: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleStopEditingLabels = (): void => {
|
||||||
|
this.setState({isEditingTaskLabels: false})
|
||||||
|
}
|
||||||
|
|
||||||
|
private get renderLabelEditorOverlay(): JSX.Element {
|
||||||
|
const {onAddTaskLabels, onRemoveTaskLabels} = this.props
|
||||||
|
const {isEditingTaskLabels, taskLabelsEdit} = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayTechnology visible={isEditingTaskLabels}>
|
||||||
|
<EditLabelsOverlay<Task>
|
||||||
|
resource={taskLabelsEdit}
|
||||||
|
onDismissOverlay={this.handleStopEditingLabels}
|
||||||
|
onAddLabels={onAddTaskLabels}
|
||||||
|
onRemoveLabels={onRemoveTaskLabels}
|
||||||
|
/>
|
||||||
|
</OverlayTechnology>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,12 @@ exports[`Tasks.Components.TaskRow renders 1`] = `
|
||||||
>
|
>
|
||||||
pasdlak
|
pasdlak
|
||||||
</a>
|
</a>
|
||||||
|
<LabelContainer
|
||||||
|
className="index-list--labels"
|
||||||
|
limitChildCount={4}
|
||||||
|
onEdit={[Function]}
|
||||||
|
resourceName="this resource"
|
||||||
|
/>
|
||||||
</ComponentSpacer>
|
</ComponentSpacer>
|
||||||
</IndexListRowCell>
|
</IndexListRowCell>
|
||||||
<IndexListRowCell
|
<IndexListRowCell
|
||||||
|
|
|
@ -1,138 +1,148 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`TasksList rendering renders 1`] = `
|
exports[`TasksList rendering renders 1`] = `
|
||||||
<IndexList>
|
<Fragment>
|
||||||
<IndexListHeader>
|
<IndexList>
|
||||||
<IndexListHeaderCell
|
<IndexListHeader>
|
||||||
alignment="left"
|
<IndexListHeaderCell
|
||||||
columnName="Name"
|
alignment="left"
|
||||||
onClick={[Function]}
|
columnName="Name"
|
||||||
sort="none"
|
onClick={[Function]}
|
||||||
sortKey="name"
|
sort="none"
|
||||||
width="20%"
|
sortKey="name"
|
||||||
/>
|
width="20%"
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName="Active"
|
|
||||||
onClick={[Function]}
|
|
||||||
sort="none"
|
|
||||||
sortKey="status"
|
|
||||||
width="10%"
|
|
||||||
/>
|
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName="Schedule"
|
|
||||||
onClick={[Function]}
|
|
||||||
sort="none"
|
|
||||||
sortKey="every"
|
|
||||||
width="20%"
|
|
||||||
/>
|
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName="Owner"
|
|
||||||
onClick={[Function]}
|
|
||||||
sort="none"
|
|
||||||
sortKey="organization.name"
|
|
||||||
width="15%"
|
|
||||||
/>
|
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName=""
|
|
||||||
width="35%"
|
|
||||||
/>
|
|
||||||
</IndexListHeader>
|
|
||||||
<IndexListBody
|
|
||||||
columnCount={5}
|
|
||||||
emptyState={
|
|
||||||
<EmptyTasksLists
|
|
||||||
onCreate={[Function]}
|
|
||||||
searchTerm=""
|
|
||||||
/>
|
/>
|
||||||
}
|
<IndexListHeaderCell
|
||||||
>
|
alignment="left"
|
||||||
<SortingHat
|
columnName="Active"
|
||||||
direction="desc"
|
onClick={[Function]}
|
||||||
list={
|
sort="none"
|
||||||
Array [
|
sortKey="status"
|
||||||
Object {
|
width="10%"
|
||||||
"cron": "2 0 * * *",
|
/>
|
||||||
"flux": "option task = {
|
<IndexListHeaderCell
|
||||||
|
alignment="left"
|
||||||
|
columnName="Schedule"
|
||||||
|
onClick={[Function]}
|
||||||
|
sort="none"
|
||||||
|
sortKey="every"
|
||||||
|
width="20%"
|
||||||
|
/>
|
||||||
|
<IndexListHeaderCell
|
||||||
|
alignment="left"
|
||||||
|
columnName="Owner"
|
||||||
|
onClick={[Function]}
|
||||||
|
sort="none"
|
||||||
|
sortKey="organization.name"
|
||||||
|
width="15%"
|
||||||
|
/>
|
||||||
|
<IndexListHeaderCell
|
||||||
|
alignment="left"
|
||||||
|
columnName=""
|
||||||
|
width="35%"
|
||||||
|
/>
|
||||||
|
</IndexListHeader>
|
||||||
|
<IndexListBody
|
||||||
|
columnCount={5}
|
||||||
|
emptyState={
|
||||||
|
<EmptyTasksLists
|
||||||
|
onCreate={[Function]}
|
||||||
|
searchTerm=""
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SortingHat
|
||||||
|
direction="desc"
|
||||||
|
list={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"cron": "2 0 * * *",
|
||||||
|
"flux": "option task = {
|
||||||
name: \\"pasdlak\\",
|
name: \\"pasdlak\\",
|
||||||
cron: \\"2 0 * * *\\"
|
cron: \\"2 0 * * *\\"
|
||||||
}
|
}
|
||||||
from(bucket: \\"inbucket\\")
|
from(bucket: \\"inbucket\\")
|
||||||
|> range(start: -1h)",
|
|> range(start: -1h)",
|
||||||
"id": "02ef9deff2141000",
|
"id": "02ef9deff2141000",
|
||||||
"labels": Array [],
|
"labels": Array [],
|
||||||
"name": "pasdlak",
|
"name": "pasdlak",
|
||||||
"orgID": "02ee9e2a29d73000",
|
"orgID": "02ee9e2a29d73000",
|
||||||
"organization": Object {
|
"organization": Object {
|
||||||
"id": "02ee9e2a29d73000",
|
"id": "02ee9e2a29d73000",
|
||||||
"links": Object {
|
"links": Object {
|
||||||
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
||||||
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
||||||
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
||||||
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
||||||
|
},
|
||||||
|
"name": "RadicalOrganization",
|
||||||
},
|
},
|
||||||
"name": "RadicalOrganization",
|
"owner": Object {
|
||||||
|
"id": "02ee9e2a19d73000",
|
||||||
|
"name": "",
|
||||||
|
},
|
||||||
|
"status": "active",
|
||||||
},
|
},
|
||||||
"owner": Object {
|
Object {
|
||||||
"id": "02ee9e2a19d73000",
|
"every": "1m0s",
|
||||||
"name": "",
|
"flux": "option task = {
|
||||||
},
|
|
||||||
"status": "active",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"every": "1m0s",
|
|
||||||
"flux": "option task = {
|
|
||||||
name: \\"somename\\",
|
name: \\"somename\\",
|
||||||
every: 1m,
|
every: 1m,
|
||||||
}
|
}
|
||||||
from(bucket: \\"inbucket\\")
|
from(bucket: \\"inbucket\\")
|
||||||
|> range(start: -task.every)",
|
|> range(start: -task.every)",
|
||||||
"id": "02f12c50dba72000",
|
"id": "02f12c50dba72000",
|
||||||
"labels": Array [
|
"labels": Array [
|
||||||
Object {
|
Object {
|
||||||
"name": "Trogdor",
|
"name": "Trogdor",
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
"color": "#44ffcc",
|
"color": "#44ffcc",
|
||||||
"description": "Burninating the countryside",
|
"description": "Burninating the countryside",
|
||||||
|
},
|
||||||
|
"resourceID": "dashboard-mock-label-a",
|
||||||
},
|
},
|
||||||
"resourceID": "dashboard-mock-label-a",
|
Object {
|
||||||
},
|
"name": "Strawberry",
|
||||||
Object {
|
"properties": Object {
|
||||||
"name": "Strawberry",
|
"color": "#ff0054",
|
||||||
"properties": Object {
|
"description": "It is a great fruit",
|
||||||
"color": "#ff0054",
|
},
|
||||||
"description": "It is a great fruit",
|
"resourceID": "dashboard-mock-label-b",
|
||||||
},
|
},
|
||||||
"resourceID": "dashboard-mock-label-b",
|
],
|
||||||
|
"name": "somename",
|
||||||
|
"orgID": "02ee9e2a29d73000",
|
||||||
|
"organization": Object {
|
||||||
|
"id": "02ee9e2a29d73000",
|
||||||
|
"links": Object {
|
||||||
|
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
||||||
|
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
||||||
|
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
||||||
|
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
||||||
|
},
|
||||||
|
"name": "RadicalOrganization",
|
||||||
},
|
},
|
||||||
],
|
"owner": Object {
|
||||||
"name": "somename",
|
"id": "02ee9e2a19d73000",
|
||||||
"orgID": "02ee9e2a29d73000",
|
"name": "",
|
||||||
"organization": Object {
|
|
||||||
"id": "02ee9e2a29d73000",
|
|
||||||
"links": Object {
|
|
||||||
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
|
||||||
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
|
||||||
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
|
||||||
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
|
||||||
},
|
},
|
||||||
"name": "RadicalOrganization",
|
"status": "active",
|
||||||
},
|
},
|
||||||
"owner": Object {
|
]
|
||||||
"id": "02ee9e2a19d73000",
|
}
|
||||||
"name": "",
|
sortKey={null}
|
||||||
},
|
>
|
||||||
"status": "active",
|
<Component />
|
||||||
},
|
</SortingHat>
|
||||||
]
|
</IndexListBody>
|
||||||
}
|
</IndexList>
|
||||||
sortKey={null}
|
<OverlayTechnology
|
||||||
>
|
visible={false}
|
||||||
<Component />
|
>
|
||||||
</SortingHat>
|
<EditLabelsOverlay
|
||||||
</IndexListBody>
|
onDismissOverlay={[Function]}
|
||||||
</IndexList>
|
resource={null}
|
||||||
|
/>
|
||||||
|
</OverlayTechnology>
|
||||||
|
</Fragment>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -21,6 +21,8 @@ import {
|
||||||
setShowInactive as setShowInactiveAction,
|
setShowInactive as setShowInactiveAction,
|
||||||
setDropdownOrgID as setDropdownOrgIDAction,
|
setDropdownOrgID as setDropdownOrgIDAction,
|
||||||
importScript,
|
importScript,
|
||||||
|
addTaskLabelsAsync,
|
||||||
|
removeTaskLabelsAsync,
|
||||||
} from 'src/tasks/actions/v2'
|
} from 'src/tasks/actions/v2'
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
@ -48,6 +50,8 @@ interface ConnectedDispatchProps {
|
||||||
setShowInactive: typeof setShowInactiveAction
|
setShowInactive: typeof setShowInactiveAction
|
||||||
setDropdownOrgID: typeof setDropdownOrgIDAction
|
setDropdownOrgID: typeof setDropdownOrgIDAction
|
||||||
importScript: typeof importScript
|
importScript: typeof importScript
|
||||||
|
onAddTaskLabels: typeof addTaskLabelsAsync
|
||||||
|
onRemoveTaskLabels: typeof removeTaskLabelsAsync
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConnectedStateProps {
|
interface ConnectedStateProps {
|
||||||
|
@ -61,7 +65,8 @@ interface ConnectedStateProps {
|
||||||
type Props = ConnectedDispatchProps & PassedInProps & ConnectedStateProps
|
type Props = ConnectedDispatchProps & PassedInProps & ConnectedStateProps
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
isOverlayVisible: boolean
|
isImportOverlayVisible: boolean
|
||||||
|
taskLabelsEdit: Task
|
||||||
}
|
}
|
||||||
|
|
||||||
@ErrorHandling
|
@ErrorHandling
|
||||||
|
@ -75,7 +80,10 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
props.setDropdownOrgID(null)
|
props.setDropdownOrgID(null)
|
||||||
|
|
||||||
this.state = {isOverlayVisible: false}
|
this.state = {
|
||||||
|
isImportOverlayVisible: false,
|
||||||
|
taskLabelsEdit: null,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
|
@ -84,6 +92,8 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
searchTerm,
|
searchTerm,
|
||||||
setShowInactive,
|
setShowInactive,
|
||||||
showInactive,
|
showInactive,
|
||||||
|
onAddTaskLabels,
|
||||||
|
onRemoveTaskLabels,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -106,6 +116,8 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
onDelete={this.handleDelete}
|
onDelete={this.handleDelete}
|
||||||
onCreate={this.handleCreateTask}
|
onCreate={this.handleCreateTask}
|
||||||
onSelect={this.props.selectTask}
|
onSelect={this.props.selectTask}
|
||||||
|
onAddTaskLabels={onAddTaskLabels}
|
||||||
|
onRemoveTaskLabels={onRemoveTaskLabels}
|
||||||
/>
|
/>
|
||||||
{this.hiddenTaskAlert}
|
{this.hiddenTaskAlert}
|
||||||
</div>
|
</div>
|
||||||
|
@ -134,7 +146,7 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleToggleOverlay = () => {
|
private handleToggleOverlay = () => {
|
||||||
this.setState({isOverlayVisible: !this.state.isOverlayVisible})
|
this.setState({isImportOverlayVisible: !this.state.isImportOverlayVisible})
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSave = (script: string, fileName: string) => {
|
private handleSave = (script: string, fileName: string) => {
|
||||||
|
@ -142,10 +154,10 @@ class TasksPage extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private get renderImportOverlay(): JSX.Element {
|
private get renderImportOverlay(): JSX.Element {
|
||||||
const {isOverlayVisible} = this.state
|
const {isImportOverlayVisible} = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OverlayTechnology visible={isOverlayVisible}>
|
<OverlayTechnology visible={isImportOverlayVisible}>
|
||||||
<ImportTaskOverlay
|
<ImportTaskOverlay
|
||||||
onDismissOverlay={this.handleToggleOverlay}
|
onDismissOverlay={this.handleToggleOverlay}
|
||||||
onSave={this.handleSave}
|
onSave={this.handleSave}
|
||||||
|
@ -224,6 +236,8 @@ const mdtp: ConnectedDispatchProps = {
|
||||||
setShowInactive: setShowInactiveAction,
|
setShowInactive: setShowInactiveAction,
|
||||||
setDropdownOrgID: setDropdownOrgIDAction,
|
setDropdownOrgID: setDropdownOrgIDAction,
|
||||||
importScript,
|
importScript,
|
||||||
|
onRemoveTaskLabels: removeTaskLabelsAsync,
|
||||||
|
onAddTaskLabels: addTaskLabelsAsync,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect<
|
export default connect<
|
||||||
|
|
|
@ -1,138 +1,148 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`TasksList rendering renders 1`] = `
|
exports[`TasksList rendering renders 1`] = `
|
||||||
<IndexList>
|
<Fragment>
|
||||||
<IndexListHeader>
|
<IndexList>
|
||||||
<IndexListHeaderCell
|
<IndexListHeader>
|
||||||
alignment="left"
|
<IndexListHeaderCell
|
||||||
columnName="Name"
|
alignment="left"
|
||||||
onClick={[Function]}
|
columnName="Name"
|
||||||
sort="none"
|
onClick={[Function]}
|
||||||
sortKey="name"
|
sort="none"
|
||||||
width="20%"
|
sortKey="name"
|
||||||
/>
|
width="20%"
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName="Active"
|
|
||||||
onClick={[Function]}
|
|
||||||
sort="none"
|
|
||||||
sortKey="status"
|
|
||||||
width="10%"
|
|
||||||
/>
|
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName="Schedule"
|
|
||||||
onClick={[Function]}
|
|
||||||
sort="none"
|
|
||||||
sortKey="every"
|
|
||||||
width="20%"
|
|
||||||
/>
|
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName="Owner"
|
|
||||||
onClick={[Function]}
|
|
||||||
sort="none"
|
|
||||||
sortKey="organization.name"
|
|
||||||
width="15%"
|
|
||||||
/>
|
|
||||||
<IndexListHeaderCell
|
|
||||||
alignment="left"
|
|
||||||
columnName=""
|
|
||||||
width="35%"
|
|
||||||
/>
|
|
||||||
</IndexListHeader>
|
|
||||||
<IndexListBody
|
|
||||||
columnCount={5}
|
|
||||||
emptyState={
|
|
||||||
<EmptyTasksLists
|
|
||||||
onCreate={[Function]}
|
|
||||||
searchTerm=""
|
|
||||||
/>
|
/>
|
||||||
}
|
<IndexListHeaderCell
|
||||||
>
|
alignment="left"
|
||||||
<SortingHat
|
columnName="Active"
|
||||||
direction="desc"
|
onClick={[Function]}
|
||||||
list={
|
sort="none"
|
||||||
Array [
|
sortKey="status"
|
||||||
Object {
|
width="10%"
|
||||||
"cron": "2 0 * * *",
|
/>
|
||||||
"flux": "option task = {
|
<IndexListHeaderCell
|
||||||
|
alignment="left"
|
||||||
|
columnName="Schedule"
|
||||||
|
onClick={[Function]}
|
||||||
|
sort="none"
|
||||||
|
sortKey="every"
|
||||||
|
width="20%"
|
||||||
|
/>
|
||||||
|
<IndexListHeaderCell
|
||||||
|
alignment="left"
|
||||||
|
columnName="Owner"
|
||||||
|
onClick={[Function]}
|
||||||
|
sort="none"
|
||||||
|
sortKey="organization.name"
|
||||||
|
width="15%"
|
||||||
|
/>
|
||||||
|
<IndexListHeaderCell
|
||||||
|
alignment="left"
|
||||||
|
columnName=""
|
||||||
|
width="35%"
|
||||||
|
/>
|
||||||
|
</IndexListHeader>
|
||||||
|
<IndexListBody
|
||||||
|
columnCount={5}
|
||||||
|
emptyState={
|
||||||
|
<EmptyTasksLists
|
||||||
|
onCreate={[Function]}
|
||||||
|
searchTerm=""
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SortingHat
|
||||||
|
direction="desc"
|
||||||
|
list={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"cron": "2 0 * * *",
|
||||||
|
"flux": "option task = {
|
||||||
name: \\"pasdlak\\",
|
name: \\"pasdlak\\",
|
||||||
cron: \\"2 0 * * *\\"
|
cron: \\"2 0 * * *\\"
|
||||||
}
|
}
|
||||||
from(bucket: \\"inbucket\\")
|
from(bucket: \\"inbucket\\")
|
||||||
|> range(start: -1h)",
|
|> range(start: -1h)",
|
||||||
"id": "02ef9deff2141000",
|
"id": "02ef9deff2141000",
|
||||||
"labels": Array [],
|
"labels": Array [],
|
||||||
"name": "pasdlak",
|
"name": "pasdlak",
|
||||||
"orgID": "02ee9e2a29d73000",
|
"orgID": "02ee9e2a29d73000",
|
||||||
"organization": Object {
|
"organization": Object {
|
||||||
"id": "02ee9e2a29d73000",
|
"id": "02ee9e2a29d73000",
|
||||||
"links": Object {
|
"links": Object {
|
||||||
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
||||||
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
||||||
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
||||||
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
||||||
|
},
|
||||||
|
"name": "RadicalOrganization",
|
||||||
},
|
},
|
||||||
"name": "RadicalOrganization",
|
"owner": Object {
|
||||||
|
"id": "02ee9e2a19d73000",
|
||||||
|
"name": "",
|
||||||
|
},
|
||||||
|
"status": "active",
|
||||||
},
|
},
|
||||||
"owner": Object {
|
Object {
|
||||||
"id": "02ee9e2a19d73000",
|
"every": "1m0s",
|
||||||
"name": "",
|
"flux": "option task = {
|
||||||
},
|
|
||||||
"status": "active",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"every": "1m0s",
|
|
||||||
"flux": "option task = {
|
|
||||||
name: \\"somename\\",
|
name: \\"somename\\",
|
||||||
every: 1m,
|
every: 1m,
|
||||||
}
|
}
|
||||||
from(bucket: \\"inbucket\\")
|
from(bucket: \\"inbucket\\")
|
||||||
|> range(start: -task.every)",
|
|> range(start: -task.every)",
|
||||||
"id": "02f12c50dba72000",
|
"id": "02f12c50dba72000",
|
||||||
"labels": Array [
|
"labels": Array [
|
||||||
Object {
|
Object {
|
||||||
"name": "Trogdor",
|
"name": "Trogdor",
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
"color": "#44ffcc",
|
"color": "#44ffcc",
|
||||||
"description": "Burninating the countryside",
|
"description": "Burninating the countryside",
|
||||||
|
},
|
||||||
|
"resourceID": "dashboard-mock-label-a",
|
||||||
},
|
},
|
||||||
"resourceID": "dashboard-mock-label-a",
|
Object {
|
||||||
},
|
"name": "Strawberry",
|
||||||
Object {
|
"properties": Object {
|
||||||
"name": "Strawberry",
|
"color": "#ff0054",
|
||||||
"properties": Object {
|
"description": "It is a great fruit",
|
||||||
"color": "#ff0054",
|
},
|
||||||
"description": "It is a great fruit",
|
"resourceID": "dashboard-mock-label-b",
|
||||||
},
|
},
|
||||||
"resourceID": "dashboard-mock-label-b",
|
],
|
||||||
|
"name": "somename",
|
||||||
|
"orgID": "02ee9e2a29d73000",
|
||||||
|
"organization": Object {
|
||||||
|
"id": "02ee9e2a29d73000",
|
||||||
|
"links": Object {
|
||||||
|
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
||||||
|
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
||||||
|
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
||||||
|
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
||||||
|
},
|
||||||
|
"name": "RadicalOrganization",
|
||||||
},
|
},
|
||||||
],
|
"owner": Object {
|
||||||
"name": "somename",
|
"id": "02ee9e2a19d73000",
|
||||||
"orgID": "02ee9e2a29d73000",
|
"name": "",
|
||||||
"organization": Object {
|
|
||||||
"id": "02ee9e2a29d73000",
|
|
||||||
"links": Object {
|
|
||||||
"buckets": "/api/v2/buckets?org=RadicalOrganization",
|
|
||||||
"dashboards": "/api/v2/dashboards?org=RadicalOrganization",
|
|
||||||
"self": "/api/v2/orgs/02ee9e2a29d73000",
|
|
||||||
"tasks": "/api/v2/tasks?org=RadicalOrganization",
|
|
||||||
},
|
},
|
||||||
"name": "RadicalOrganization",
|
"status": "active",
|
||||||
},
|
},
|
||||||
"owner": Object {
|
]
|
||||||
"id": "02ee9e2a19d73000",
|
}
|
||||||
"name": "",
|
sortKey={null}
|
||||||
},
|
>
|
||||||
"status": "active",
|
<Component />
|
||||||
},
|
</SortingHat>
|
||||||
]
|
</IndexListBody>
|
||||||
}
|
</IndexList>
|
||||||
sortKey={null}
|
<OverlayTechnology
|
||||||
>
|
visible={false}
|
||||||
<Component />
|
>
|
||||||
</SortingHat>
|
<EditLabelsOverlay
|
||||||
</IndexListBody>
|
onDismissOverlay={[Function]}
|
||||||
</IndexList>
|
resource={null}
|
||||||
|
/>
|
||||||
|
</OverlayTechnology>
|
||||||
|
</Fragment>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -93,6 +93,35 @@ export default (state: State = defaultState, action: Action): State => {
|
||||||
case 'SET_DROPDOWN_ORG_ID':
|
case 'SET_DROPDOWN_ORG_ID':
|
||||||
const {dropdownOrgID} = action.payload
|
const {dropdownOrgID} = action.payload
|
||||||
return {...state, dropdownOrgID}
|
return {...state, dropdownOrgID}
|
||||||
|
case 'ADD_TASK_LABELS':
|
||||||
|
const {taskID, labels} = action.payload
|
||||||
|
|
||||||
|
const updatedTasks = state.tasks.map(t => {
|
||||||
|
if (t.id === taskID) {
|
||||||
|
return {...t, labels: [...labels]}
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
})
|
||||||
|
|
||||||
|
return {...state, tasks: [...updatedTasks]}
|
||||||
|
case 'REMOVE_TASK_LABELS': {
|
||||||
|
const {taskID, labels} = action.payload
|
||||||
|
|
||||||
|
const updatedTasks = state.tasks.map(t => {
|
||||||
|
if (t.id === taskID) {
|
||||||
|
const updatedLabels = t.labels.filter(l => {
|
||||||
|
if (!labels.find(label => label.name === l.name)) {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {...t, labels: updatedLabels}
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
})
|
||||||
|
|
||||||
|
return {...state, tasks: [...updatedTasks]}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue