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

chore(node)!: update 16.14 -> 18.16 #1600

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 5 additions & 5 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
strategy:
matrix:
node-version:
- 16.14.0-buster
- 18.16.0-buster

container:
image: node:${{ matrix.node-version }}
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- name: Login to GAR
uses: docker/login-action@v1
with:
registry: us-east4-docker.pkg.dev
registry: us-west1-docker.pkg.dev
username: _json_key
password: ${{ secrets.GCR_JSON_KEY }}

Expand All @@ -120,8 +120,8 @@ jobs:
build-args: |
SPOKE_VERSION=${{ steps.image-tags.outputs.version }}
tags: |
us-east4-docker.pkg.dev/spoke-rewired/spoke/core:latest
us-east4-docker.pkg.dev/spoke-rewired/spoke/core:${{ steps.image-tags.outputs.version }}
us-east4-docker.pkg.dev/spoke-rewired/spoke/core:${{ steps.image-tags.outputs.sha }}
us-west1-docker.pkg.dev/spoke-407503/spoke/core:latest
us-west1-docker.pkg.dev/spoke-407503/spoke/core:${{ steps.image-tags.outputs.version }}
us-west1-docker.pkg.dev/spoke-407503/spoke/core:${{ steps.image-tags.outputs.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
cut-gh-release:
runs-on: ubuntu-latest
env:
DOCKER_IMAGE: us-east4-docker.pkg.dev/spoke-rewired/spoke/core
DOCKER_IMAGE: us-west1-docker.pkg.dev/spoke-407503/spoke/core
BODY_PATH: release-body.txt
steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16.14
18.16
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [8.0.1](https://github.com/politics-rewired/spoke/compare/v8.0.0...v8.0.1) (2024-02-15)


### Bug Fixes

* **mms:** get feature for max sms segment length ([#4](https://github.com/politics-rewired/spoke/issues/4)) ([f19b366](https://github.com/politics-rewired/spoke/commit/f19b366e2c83a742409756d6544644fed5dd274c))

## [8.0.0](https://github.com/politics-rewired/spoke/compare/v7.3.0...v8.0.0) (2024-02-15)


### Features

* support sending mms without media ([#2](https://github.com/politics-rewired/spoke/issues/2)) ([3db7d25](https://github.com/politics-rewired/spoke/commit/3db7d25474601b087895be04aa2edc92d00bbb13))

## [7.3.0](https://github.com/politics-rewired/spoke/compare/v7.2.0...v7.3.0) (2023-12-10)


Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### Dependency Cacher
### -------------------------
FROM endeveit/docker-jq:latest as deps

Check warning on line 3 in Dockerfile

View workflow job for this annotation

GitHub Actions / Hadolint

Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag

# To prevent cache invalidation from changes in fields other than dependencies
# https://stackoverflow.com/a/59606373
Expand All @@ -10,7 +10,7 @@

### Fat Build
### -------------------------
FROM node:16.14.0 AS builder
FROM node:18.16.0 AS builder

WORKDIR /usr/Spoke

Expand All @@ -36,14 +36,14 @@

### Slim Deploy
### -------------------------
FROM node:16.14.0
FROM node:18.16.0

WORKDIR /usr/Spoke

# Install and cache production dependencies
COPY --from=deps /tmp/deps.json ./package.json
COPY yarn.lock ./
RUN yarn install --production

Check notice on line 46 in Dockerfile

View workflow job for this annotation

GitHub Actions / Hadolint

`yarn cache clean` missing after `yarn install` was run.

# Copy only the built source
COPY --from=builder /usr/Spoke/build ./build
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ that goal. See [`HOWTO_migrate-from-moveon-main.md`](./docs/HOWTO_migrate-from-m

Runtimes and package managers:

- Node (^16.14)
- Yarn (>= 1.19.1)
- Node (^18.16) -- See [How to Install Node](https://nodejs.dev/learn/how-to-install-nodejs)
- Yarn (>= 1.19.1) -- See [Installing Yarn](https://classic.yarnpkg.com/en/docs/install)

External services:

- Postgres (>= 11)
- Postgres (>= 11) -- See [install](https://postgresql.org/download) and [start](https://www.postgresql.org/docs/current/server-start.html) documentation

Recommended:

Expand Down
2 changes: 2 additions & 0 deletions libs/gql-schema/organization-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const schema = `
showDoNotAssignMessage: Boolean
doNotAssignMessage: String
defaultAutosendingControlsMode: AutosendingControlsMode
maxSmsSegmentLength: Int

# Superadmin
startCampaignRequiresApproval: Boolean
Expand All @@ -28,6 +29,7 @@ export const schema = `
confirmationClickForScriptLinks: Boolean!
showDoNotAssignMessage: Boolean!
doNotAssignMessage: String!
maxSmsSegmentLength: Int

# Supervolunteer
startCampaignRequiresApproval: Boolean
Expand Down
23 changes: 23 additions & 0 deletions libs/spoke-codegen/src/graphql/general-settings.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,26 @@ mutation UpdateAutosendingSettings(
defaultAutosendingControlsMode
}
}

query GetMessageSendingSettings($organizationId: String!) {
organization(id: $organizationId) {
id
settings {
id
maxSmsSegmentLength
}
}
}

mutation UpdateMessageSendingSettings(
$organizationId: String!
$maxSmsSegmentLength: Int
) {
editOrganizationSettings(
id: $organizationId
input: { maxSmsSegmentLength: $maxSmsSegmentLength }
) {
id
maxSmsSegmentLength
}
}
1 change: 1 addition & 0 deletions libs/spoke-codegen/src/graphql/spoke-context.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ fragment OrganizationSettingsInfo on OrganizationSettings {
scriptPreviewForSupervolunteers
defaultCampaignBuilderMode
defaultAutosendingControlsMode
maxSmsSegmentLength
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "spoke",
"version": "7.3.0",
"version": "8.0.1",
"description": "Spoke",
"main": "src/server",
"engines": {
"npm": "please-use-yarn",
"yarn": ">= 1.19.1",
"node": "^16.14.0"
"node": "^18.16.0"
},
"scripts": {
"preinstall": "node -e \"if(process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('spoke must be installed with Yarn: https://yarnpkg.com/')\"",
Expand Down Expand Up @@ -129,7 +129,7 @@
"graphql-type-json": "^0.3.2",
"graphql-upload": "^13.0.0",
"history": "^5.0.0",
"hot-shots": "^8.3.0",
"hot-shots": "^10.0.0",
"humps": "^1.1.0",
"iconv-lite": "^0.5.1",
"immer": "^8.0.1",
Expand Down
7 changes: 3 additions & 4 deletions src/components/MessageLengthInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { getCharCount } from "@trt2/gsm-charset-utils";
import PropTypes from "prop-types";
import React from "react";

import { replaceEasyGsmWins } from "../lib/charset-utils";
import { getSpokeCharCount } from "../lib/charset-utils";

const MessageLengthInfo: React.SFC<{ messageText: string }> = ({
messageText
}) => {
const { charCount, msgCount, charsPerSegment } = getCharCount(
replaceEasyGsmWins(messageText)
const { charCount, msgCount, charsPerSegment } = getSpokeCharCount(
messageText
);
const segmentInfo = msgCount === 1 ? "(1 segment)" : `(${msgCount} segments)`;

Expand Down
10 changes: 5 additions & 5 deletions src/components/ScriptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { withApollo } from "@apollo/client/react/hoc";
import { blue, green, grey, orange, red } from "@material-ui/core/colors";
import type { CampaignVariable } from "@spoke/spoke-codegen";
import { IsValidAttachmentDocument } from "@spoke/spoke-codegen";
import { getCharCount } from "@trt2/gsm-charset-utils";
import type { ContentBlock } from "draft-js";
import {
CompositeDecorator,
Expand All @@ -14,7 +13,7 @@ import {
import escapeRegExp from "lodash/escapeRegExp";
import React from "react";

import { replaceEasyGsmWins } from "../lib/charset-utils";
import { getSpokeCharCount, replaceEasyGsmWins } from "../lib/charset-utils";
import { delimit, getAttachmentLink, getMessageType } from "../lib/scripts";
import baseTheme from "../styles/theme";
import Chip from "./Chip";
Expand Down Expand Up @@ -122,6 +121,7 @@ interface Props {
scriptFields: string[];
campaignVariables: CampaignVariable[];
integrationSourced: boolean;
maxSmsSegmentLength: number | null;
onChange: (value: string) => Promise<void> | void;
receiveFocus?: boolean;
}
Expand Down Expand Up @@ -319,7 +319,7 @@ class ScriptEditor extends React.Component<Props, State> {

renderAttachmentWarning() {
const text = this.state.editorState.getCurrentContent().getPlainText();
const messageType = getMessageType(text);
const messageType = getMessageType(text, this.props.maxSmsSegmentLength);
if (messageType === "MMS" && !this.state.validAttachment) {
return (
<div style={{ color: baseTheme.colors.red }}>
Expand Down Expand Up @@ -369,8 +369,8 @@ class ScriptEditor extends React.Component<Props, State> {

render() {
const text = this.state.editorState.getCurrentContent().getPlainText();
const info = getCharCount(replaceEasyGsmWins(text));
const messageType = getMessageType(text);
const info = getSpokeCharCount(text);
const messageType = getMessageType(text, this.props.maxSmsSegmentLength);

return (
<div>
Expand Down
1 change: 1 addition & 0 deletions src/components/forms/GSScriptField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class GSScriptField extends GSFormField {
scriptFields={scriptFields}
campaignVariables={campaignVariables}
integrationSourced={integrationSourced}
maxSmsSegmentLength={orgSettings.maxSmsSegmentLength}
expandable
onChange={(val) => this.setState({ script: val })}
/>
Expand Down
1 change: 1 addition & 0 deletions src/components/forms/GSScriptOptionsField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class GSScriptOptionsField extends GSFormField {
scriptFields={scriptFields}
campaignVariables={campaignVariables}
integrationSourced={integrationSourced}
maxSmsSegmentLength={orgSettings.maxSmsSegmentLength}
receiveFocus
expandable
onChange={(val) => this.setState({ scriptDraft: val.trim() })}
Expand Down
6 changes: 6 additions & 0 deletions src/containers/Settings/components/General.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { loadData } from "../../hoc/with-operations";
import AutosendingSettingsCard from "./AutosendingSettingsCard";
import CampaignBuilderSettingsCard from "./CampaignBuilderSettingsCard";
import EditName from "./EditName";
import MessageSendingSettingsCard from "./MessageSendingSettingsCard";
import RejectedTextersMessageCard from "./RejectedTextersMessageCard";
import Review10DlcInfo from "./Review10DlcInfo";
import ScriptPreviewSettingsCard from "./ScriptPreviewSettingsCard";
Expand Down Expand Up @@ -473,6 +474,11 @@ class Settings extends React.Component {
style={{ marginBottom: 20 }}
/>

<MessageSendingSettingsCard
organizationId={organization.id}
style={{ marginBottom: 20 }}
/>

{window.ENABLE_TROLLBOT && (
<Card className={css(styles.sectionCard)}>
<GSForm
Expand Down
117 changes: 117 additions & 0 deletions src/containers/Settings/components/MessageSendingSettingsCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import CardHeader from "@material-ui/core/CardHeader";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Switch from "@material-ui/core/Switch";
import TextField from "@material-ui/core/TextField";
import Alert from "@material-ui/lab/Alert";
import {
useGetMessageSendingSettingsQuery,
useUpdateMessageSendingSettingsMutation
} from "@spoke/spoke-codegen";
import React from "react";

export interface MessageSendingSettingsCardProps {
organizationId: string;
style?: React.CSSProperties;
}

// eslint-disable-next-line max-len
export const MessageSendingSettingsCard: React.FC<MessageSendingSettingsCardProps> = (
props
) => {
const { organizationId, style } = props;

const getSettingsState = useGetMessageSendingSettingsQuery({
variables: { organizationId }
});
const settings = getSettingsState?.data?.organization?.settings;

const [
setMaxSmsSegmentLength,
updateState
] = useUpdateMessageSendingSettingsMutation();

const working = getSettingsState.loading || updateState.loading;
const errorMsg =
getSettingsState.error?.message ?? updateState.error?.message;

const maxSmsSegmentLength = settings?.maxSmsSegmentLength;
const showMaxSmsSegmentLength = maxSmsSegmentLength !== null;

const setNewMaxSmsSegmentLength = async (
newMax: number | null | undefined
) => {
await setMaxSmsSegmentLength({
variables: {
organizationId,
maxSmsSegmentLength: newMax
}
});
};

// eslint-disable-next-line max-len
const handleChangeMaxSmsSegmentLength: React.ChangeEventHandler<HTMLInputElement> = async (
event
) => {
if (working) return;
const newMax = event.target.valueAsNumber;
await setNewMaxSmsSegmentLength(newMax);
};

// eslint-disable-next-line max-len
const handleToggleMmsConversion: React.ChangeEventHandler<HTMLInputElement> = async (
event
) => {
const { checked } = event.target;
const DEFAULT_MAX_SMS_SEGMENT_LENGTH = 3;
const newMax = checked ? DEFAULT_MAX_SMS_SEGMENT_LENGTH : null;
await setNewMaxSmsSegmentLength(newMax);
};

return (
<Card style={style}>
<CardHeader title="Message Sending Settings" disableTypography />
<CardContent>
{errorMsg && <Alert severity="error">Error: {errorMsg}</Alert>}
<p>
Turn on this feature to automatically convert long SMS messages to
MMS. If turned on, SMS messages <i>longer</i> than the length you set
will be converted. For example, if you set the max length to 3, a 4
segment SMS message will be converted to MMS.
</p>
<p style={{ marginBottom: 25 }}>
Messages longer than 3 segments are usually cheaper to send as MMS.
You may notice changes in deliverability when switching from SMS to
MMS messages.{" "}
<a
href="https://docs.spokerewired.com/article/86-include-an-image-in-a-message"
target="_blank"
rel="noopener noreferrer"
>
Learn more about sending MMS here
</a>
</p>
<FormControlLabel
label="Convert long SMS messages to MMS?"
control={
<Switch
checked={showMaxSmsSegmentLength}
onChange={handleToggleMmsConversion}
/>
}
/>
{showMaxSmsSegmentLength && (
<TextField
label="Max SMS Segment Length"
type="number"
value={settings?.maxSmsSegmentLength}
onChange={handleChangeMaxSmsSegmentLength}
/>
)}
</CardContent>
</Card>
);
};

export default MessageSendingSettingsCard;
Loading
Loading