src/config-form.ts   A
last analyzed

Complexity

Total Complexity 8
Complexity/F 1.6

Size

Lines of Code 133
Function Count 5

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 70
mnd 3
bc 3
fnc 5
dl 0
loc 133
rs 10
bpm 0.6
cpm 1.6
noi 0
c 0
b 0
f 0

5 Functions

Rating   Name   Duplication   Size   Complexity  
A config-form.ts ➔ topicInput 0 14 1
A config-form.ts ➔ fixedFooter 0 13 1
B config-form.ts ➔ buildConfigurationForm 0 58 4
A config-form.ts ➔ optionInput 0 16 1
A config-form.ts ➔ helpText 0 12 1
1
import {MAX_NUM_OF_OPTIONS} from './config/default';
2
import {chat_v1 as chatV1} from '@googleapis/chat';
3
import {PollState} from './helpers/interfaces';
4
5
/** Upper bounds on number of choices to present. */
6
7
/**
8
 * Build widget with instructions on how to use form.
9
 *
10
 * @returns {object} card widget
11
 */
12
function helpText() {
13
  return {
14
    textParagraph: {
15
      text: 'Enter the poll topic and up to 10 choices in the poll. Blank options will be omitted.',
16
    },
17
  };
18
}
19
20
/**
21
 * Build the text input for a choice.
22
 *
23
 * @param {number} index - Index to identify the choice
24
 * @param {string|undefined} value - Initial value to render (optional)
25
 * @returns {object} card widget
26
 */
27
function optionInput(
28
  index: number, value: string): chatV1.Schema$GoogleAppsCardV1Widget {
29
  return {
30
    textInput: {
31
      label: `Option ${index + 1}`,
32
      type: 'SINGLE_LINE',
33
      name: `option${index}`,
34
      value: value || '',
35
    },
36
  };
37
}
38
39
/**
40
 * Build the text input for the poll topic.
41
 *
42
 * @param {string|undefined} topic - Initial value to render (optional)
43
 * @returns {object} card widget
44
 */
45
function topicInput(topic: string) {
46
  return {
47
    textInput: {
48
      label: 'Topic',
49
      type: 'MULTIPLE_LINE',
50
      name: 'topic',
51
      value: topic,
52
    },
53
  };
54
}
55
56
/**
57
 * Build the buttons/actions for the form.
58
 *
59
 * @returns {object} card widget
60
 */
61
function fixedFooter() {
62
  return {
63
    'primaryButton': {
64
      'text': 'Submit',
65
      'onClick': {
66
        'action': {
67
          'function': 'start_poll',
68
        },
69
      },
70
    },
71
  };
72
}
73
74
/**
75
 * Build the configuration form.
76
 *
77
 * @param {object} options - Initial state to render with form
78
 * @param {string|undefined} options.topic - Topic of poll (optional)
79
 * @param {string[]|undefined} options.choices - Text of choices to display to users (optional)
80
 * @returns {object} card
81
 */
82
export function buildConfigurationForm(options: PollState): chatV1.Schema$GoogleAppsCardV1Card {
83
  const widgets = [];
84
  widgets.push(helpText());
85
  widgets.push(topicInput(options.topic));
86
  for (let i = 0; i < MAX_NUM_OF_OPTIONS; ++i) {
87
    const choice = options?.choices?.[i];
88
    widgets.push(optionInput(i, choice));
89
  }
90
91
  // Assemble the card
92
  return {
93
    'sections': [
94
      {
95
        'collapsible': true,
96
        'uncollapsibleWidgetsCount': 6,
97
        widgets,
98
      },
99
      {
100
        'widgets': [
101
          {
102
            'decoratedText': {
103
              'bottomLabel': 'If this checked the voters name will be not shown',
104
              'text': 'Anonymous voter',
105
              'switchControl': {
106
                'controlType': 'SWITCH',
107
                'name': 'is_anonymous',
108
                'value': '1',
109
                'selected': false,
110
              },
111
            },
112
            'horizontalAlignment': 'CENTER',
113
          },
114
          {
115
            'decoratedText': {
116
              'bottomLabel': 'After the poll is created, other member can add more option',
117
              'text': 'Allow to add more option(s)',
118
              'switchControl': {
119
                'controlType': 'SWITCH',
120
                'name': 'allow_add_option',
121
                'value': '1',
122
                'selected': true,
123
              },
124
            },
125
            'horizontalAlignment': 'CENTER',
126
          },
127
        ],
128
      },
129
    ],
130
    'fixedFooter': fixedFooter(),
131
  };
132
}
133