diff --git a/functions/internals/i18n.ts b/functions/internals/i18n.ts index 7e71e9a..b263b43 100644 --- a/functions/internals/i18n.ts +++ b/functions/internals/i18n.ts @@ -69,7 +69,7 @@ labels[Label.ProjectCode] = { "ja": "プロジェクトコード" }; labels[Label.ProjectName] = { "ja": "プロジェクト名" }; labels[Label.ProjectIsActive] = { "ja": "利用可能" }; labels[Label.ProjectDescription] = { "ja": "説明・メモ" }; -labels[Label.ManualEntryPermitted] = { "ja": "履歴の手入力・編集を許可する" }; +labels[Label.ManualEntryPermitted] = { "ja": "履歴の手入力・編集" }; labels[Label.OrganizationPolicyValue_Permitted] = { "ja": "可" }; labels[Label.OrganizationPolicyValue_Restricted] = { "ja": "不可" }; // Admin report UI messages diff --git a/functions/internals/organization_policies.ts b/functions/internals/organization_policies.ts index cfee82b..5cb78db 100644 --- a/functions/internals/organization_policies.ts +++ b/functions/internals/organization_policies.ts @@ -5,6 +5,7 @@ import { Label } from "./constants.ts"; export interface OrganizationPolicyDetails { label: string; values: OrganizationPolicyValueDetails[]; + mustSelectOne: boolean; } export interface OrganizationPolicyValueDetails { value: string; @@ -15,11 +16,14 @@ export const OrganizationPolices: Record = export class OrganizationPolicyKey { static IsManualEntryPermitted = "is_manual_entry_permitted"; + static Country = "country"; } export class OrganizationPolicyValue { static Permitted = "permitted"; static Restricted = "restricted"; + static Japan = "jp"; + static UnitedStates = "us"; } // slack datastore put '{"datastore":"organization_policies","item": {"key":"is_manual_entry_permitted","value":"restricted"}}' @@ -35,6 +39,15 @@ OrganizationPolices[OrganizationPolicyKey.IsManualEntryPermitted] = { label: Label.OrganizationPolicyValue_Restricted, }, ], + mustSelectOne: true, +}; +OrganizationPolices[OrganizationPolicyKey.Country] = { + label: Label.Country, + values: [ + { value: OrganizationPolicyValue.Japan, label: Label.Japan }, + { value: OrganizationPolicyValue.UnitedStates, label: Label.UnitedStates }, + ], + mustSelectOne: false, }; interface isManualEntryPermittedArgs { @@ -50,3 +63,13 @@ export async function isManualEntryPermitted( } return true; } + +interface fetchDefaultCountryArgs { + op: DataMapper; +} +export async function fetchDefaultCountryId( + { op }: fetchDefaultCountryArgs, +): Promise { + const row = await op.findById(OrganizationPolicyKey.Country); + return row.item.value; +} diff --git a/functions/internals/views.ts b/functions/internals/views.ts index b5c24f9..1e33f49 100644 --- a/functions/internals/views.ts +++ b/functions/internals/views.ts @@ -12,6 +12,7 @@ import { PlainTextOption, RichTextBlock, SlackAPIClient, + StaticSelect, } from "slack-web-api-client/mod.ts"; import { i18n } from "./i18n.ts"; @@ -717,6 +718,7 @@ interface toUserSettingsViewArgs { view: ModalView; settings: SavedAttributes; countries: SavedAttributes[]; + defaultCountryId: string | undefined; language: string; country: string | undefined; } @@ -725,6 +727,7 @@ export function toUserSettingsView({ view, settings, countries, + defaultCountryId, language, country, }: toUserSettingsViewArgs): ModalView { @@ -750,8 +753,9 @@ export function toUserSettingsView({ }, }); const options = CountryOptions(countries, language); + const countryId = settings.country_id ?? defaultCountryId; if (options && options.length > 0) { - let selectedOption = options.find((c) => c.value === settings.country_id); + let selectedOption = options.find((c) => c.value === countryId); if (!selectedOption) { selectedOption = options.find((c) => c.value === country); } @@ -1539,7 +1543,7 @@ export function toOrganizationPoliciesView({ value: key + "___" + v.value, }); } - let selectedOption = options[0]; + let selectedOption = details.mustSelectOne ? options[0] : undefined; const saved = policies.find((p) => p.key === key); if (saved) { const savedOption = options.find((o) => @@ -1547,15 +1551,16 @@ export function toOrganizationPoliciesView({ ); if (savedOption) selectedOption = savedOption; } + const element: StaticSelect = { + "type": "static_select", + "action_id": ActionId.OrganizationPolicyChange, + "options": options, + }; + if (selectedOption) element.initial_option = selectedOption; view.blocks.push({ "type": "section", "text": { "type": "mrkdwn", "text": i18n(details.label, language) }, - "accessory": { - "type": "static_select", - "action_id": ActionId.OrganizationPolicyChange, - "options": options, - "initial_option": selectedOption, - }, + "accessory": element, }); } return view; diff --git a/functions/run_timesheet.ts b/functions/run_timesheet.ts index 54074f5..6ae9730 100644 --- a/functions/run_timesheet.ts +++ b/functions/run_timesheet.ts @@ -79,6 +79,7 @@ import { validateTimeEntrySubmission, } from "./internals/validation.ts"; import { + fetchDefaultCountryId, isManualEntryPermitted, OrganizationPolices, } from "./internals/organization_policies.ts"; @@ -123,7 +124,13 @@ export default SlackFunction( ...components, countries, }); - view = toUserSettingsView({ view, countries, ...components }); + const defaultCountryId = await fetchDefaultCountryId({ ...components }); + view = toUserSettingsView({ + view, + countries, + defaultCountryId, + ...components, + }); } else { const item = await fetchTimeEntry({ ...components }); const manualEntryPermitted = await isManualEntryPermitted({ @@ -620,6 +627,7 @@ export default SlackFunction( view: toUserSettingsView({ view: newView(language), countries: await fetchAllCountries({ ...components }), + defaultCountryId: undefined, // no need to use this here ...components, }), });