Skip to content

Commit 0eaf880

Browse files
committed
feat: add organisation select
1 parent b3ff449 commit 0eaf880

17 files changed

Lines changed: 7717 additions & 11 deletions

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
"prebuild": "npm run build:wasm && npm run build:licenses",
1414
"build:providers-oembed": "tsx scripts/getProvidersOembed.ts src/generated/providers-oembed.json",
1515
"build:licenses": "mkdir -p src/generated && tsx scripts/genLicenseList.ts src/generated/licenses.json",
16+
"build:organisations": "tsx src/app/data/generateOrganisations.ts",
1617
"build:wasm": "cp \"$(go env GOROOT)/misc/wasm/wasm_exec.js\" public && GOOS=js GOARCH=wasm go build -o public/main.wasm src/wasm/main.go",
1718
"serve": "rm -rf dist; npm run build && http-server dist",
1819
"format": "prettier --write 'src/**/*.{ts,tsx,scss,css,json}' ",
1920
"test": "jest --passWithNoTests",
2021
"gdeploy": "gh-pages -u 'Deploy Bot <no-reply@puzzle.ch>' -d dist",
2122
"deploy": "gh-pages -u 'Deploy Bot <no-reply@teamdigitale.governo.it>' -d dist",
2223
"release": "release-it",
24+
"postinstall": "npm run build:organisations",
2325
"_postinstall": "patch-package"
2426
},
2527
"keywords": [

src/app/components/Editor.tsx

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import useFormPersist from "react-hook-form-persist";
1212
import { useTranslation } from "react-i18next";
1313
import { RequiredDeep } from "type-fest";
1414
import licenses from "../../generated/licenses.json";
15-
import { allLangs, displayName } from "../../i18n";
15+
import organisationData from "../data/organisations.json";
16+
import { allLangs, displayName, getLocalizedText } from "../../i18n";
1617
import categories from "../contents/categories";
1718
import { DEFAULT_COUNTRY_SECTIONS } from "../contents/constants";
1819
import * as countrySection from "../contents/countrySpecificSection";
@@ -128,6 +129,7 @@ const resolver: Resolver<PublicCode | PublicCodeWithDeprecatedFields> = async (
128129
const defaultValues = {
129130
publiccodeYmlVersion: LATEST_VERSION,
130131
legal: {},
132+
organisation: {},
131133
localisation: { availableLanguages: [] },
132134
maintenance: { contacts: undefined, contractors: undefined },
133135
platforms: [],
@@ -147,7 +149,7 @@ const isNotTheSameVersion = (version1: string, version2: string) => {
147149

148150
export default function Editor() {
149151
//#region UI
150-
const { t } = useTranslation();
152+
const { t, i18n } = useTranslation();
151153
const { countrySections } = useCountryStore();
152154
const { resetWarnings, setWarnings } = useWarningStore();
153155
const {
@@ -161,6 +163,15 @@ export default function Editor() {
161163
} = useYamlStore();
162164
const { languages, setLanguages, resetLanguages } = useLanguagesStore();
163165
const { setCountrySections } = useCountryStore();
166+
167+
const organisations = organisationData.flatMap(data =>
168+
data.organisations.map(organisation => ({
169+
text: getLocalizedText(organisation.name, i18n.language),
170+
value: organisation.id,
171+
group: getLocalizedText(data.name, i18n.language) + " (" + getLocalizedText(data.abbreviation, i18n.language) + ")",
172+
}))
173+
);
174+
164175
const { showCountryExtensionVersion, setShowCountryExtensionVersion } =
165176
useITCountrySpecific();
166177
const getNestedValue = (
@@ -283,14 +294,31 @@ export default function Editor() {
283294
[setValue]
284295
);
285296

297+
const updateOrganisation = useCallback(
298+
(value: Partial<PublicCode>) => {
299+
const uri = value.organisation?.uri;
300+
301+
if (uri) {
302+
const organisation = organisations.find(o => o.value === uri);
303+
setValue("organisation.name", organisation?.text);
304+
} else {
305+
setValue("organisation", undefined)
306+
}
307+
},
308+
[organisations, setValue]
309+
)
310+
286311
useEffect(() => {
287312
const subscription = watch((value, { name }) => {
288313
if (name === "maintenance.type") {
289314
resetMaintenance(value as PublicCode);
290315
}
316+
if (name === "organisation.uri") {
317+
updateOrganisation(value as PublicCode)
318+
}
291319
});
292320
return () => subscription.unsubscribe();
293-
}, [watch, resetMaintenance]);
321+
}, [watch, resetMaintenance, updateOrganisation]);
294322
//#endregion
295323

296324
//#region form action handlers
@@ -579,9 +607,13 @@ export default function Editor() {
579607
<span>
580608
<EditorInput<"isBasedOn"> fieldName="isBasedOn" />
581609
</span>
582-
<span>
583-
<EditorInput<"organisation.uri"> fieldName="organisation.uri" />
584-
</span>
610+
<div className="mt-5">
611+
<EditorSelect<"organisation.uri">
612+
fieldName="organisation.uri"
613+
data={organisations}
614+
filter="contains"
615+
/>
616+
</div>
585617
<div className="mt-4 mb-4">
586618
<EditorFundedBy />
587619
</div>

src/app/components/EditorSelect.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import PublicCode from "../contents/publiccode";
1313
type Props<T> = {
1414
fieldName: T;
1515
required?: boolean;
16-
data: Array<{ value: string; text: string }>;
17-
filter?: Filter<{ value: string; text: string }>;
16+
data: Array<{ value: string; text: string; group?: string }>;
17+
filter?: Filter<{ value: string; text: string; group?: string }>;
1818
};
1919

2020
export default function EditorSelect<
@@ -48,10 +48,18 @@ export default function EditorSelect<
4848
onChange(value);
4949
}}
5050
value={value}
51-
data={[...(!required ? [{ text: "(unset)", value: "" }] : []), ...data]}
51+
data={[...(!required ? [{text: "", value: ""}] : []), ...data]}
5252
dataKey="value"
5353
textField="text"
54+
renderListItem={(item) => {
55+
if (item.value === "") {
56+
return <span>(unset)</span>;
57+
} else {
58+
return <span>{item.text}</span>;
59+
}
60+
}}
5461
filter={filter}
62+
groupBy={"group"}
5563
/>
5664
<small className="form-text">{description}</small>
5765
{errorMessage && (

src/app/contents/fields/generic.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ const fields = (): Array<Field> => {
7979
section: 1,
8080
widget: "url",
8181
},
82+
{
83+
type: "array",
84+
title: "uri",
85+
section: 0,
86+
items: {
87+
type: "string",
88+
enum: [],
89+
},
90+
widget: "combobox",
91+
group: "organization",
92+
},
8293
{
8394
title: "localisedName",
8495
type: "string",

src/app/contents/publiccode.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export const publicCodeDummyObjectFactory = () =>
199199
logo: "",
200200
platforms: [],
201201
categories: undefined,
202-
organisation: undefined,
202+
organisation: { uri: '' },
203203
fundedBy: [],
204204
usedBy: [],
205205
roadmap: "",
@@ -216,6 +216,7 @@ export const publicCodeDummyObjectFactory = () =>
216216

217217
export interface Organisation {
218218
uri: string;
219+
name?: string;
219220
}
220221

221222
export type { Organisation as TOrganisation };

src/app/data/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Data
2+
3+
## Organisations
4+
5+
The data in the file `organisations.json` originates from the following sources:
6+
7+
- The seven departements and the Federal Chancellery (`departements.json`)
8+
```
9+
https://ld.admin.ch/sparql/#query=PREFIX%20schema%3A%20%3Chttp%3A%2F%2Fschema.org%2F%3E%0APREFIX%20rdf%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0A%0ASELECT%20DISTINCT%20%3Fdepartment%20%3FnameDepDe%20%3FnameDepFr%20%3FnameDepIt%20%3FnameDepEn%20%3FaltNameDepDe%20%3FaltNameDepFr%20%3FaltNameDepIt%20%3FaltNameDepEn%20%3Foffice%20%3FnameDe%20%3FnameFr%20%3FnameIt%20%3FnameEn%20WHERE%20%7B%0A%20%20%0A%20%20%3Fdepartment%20schema%3AinDefinedTermSet%20%3Chttps%3A%2F%2Fld.admin.ch%2Fdimension%2Fdepartment%3E.%0A%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDe.%20FILTER(lang(%3FnameDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameFr.%20FILTER(lang(%3FnameFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameIt.%20FILTER(lang(%3FnameIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameEn.%20FILTER(lang(%3FnameEn)%20%3D%20%22en%22)%20%7D%0A%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDe.%20FILTER(lang(%3FaltNameDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameFr.%20FILTER(lang(%3FaltNameFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameIt.%20FILTER(lang(%3FaltNameIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameEn.%20FILTER(lang(%3FaltNameEn)%20%3D%20%22en%22)%20%7D%0A%20%20%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepDe.%20FILTER(lang(%3FnameDepDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepFr.%20FILTER(lang(%3FnameDepFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepIt.%20FILTER(lang(%3FnameDepIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepEn.%20FILTER(lang(%3FnameDepEn)%20%3D%20%22en%22)%20%7D%0A%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepDe.%20FILTER(lang(%3FaltNameDepDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepFr.%20FILTER(lang(%3FaltNameDepFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepIt.%20FILTER(lang(%3FaltNameDepIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepEn.%20FILTER(lang(%3FaltNameDepEn)%20%3D%20%22en%22)%20%7D%0A%0A%7D%0A&endpoint=https%3A%2F%2Fld.admin.ch%2Fquery&requestMethod=POST&tabTitle=Query&headers=%7B%7D&contentTypeConstruct=text%2Fturtle&contentTypeSelect=application%2Fsparql-results%2Bjson&outputFormat=table&outputSettings=%7B%22isEllipsed%22%3Atrue%2C%22compact%22%3Afalse%7D
10+
```
11+
12+
- All offices of the seven departments (`offices.json`)
13+
```
14+
https://ld.admin.ch/sparql/#query=PREFIX%20schema%3A%20%3Chttp%3A%2F%2Fschema.org%2F%3E%0APREFIX%20rdf%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0A%0ASELECT%20DISTINCT%20%3Fdepartment%20%3FnameDepDe%20%3FnameDepFr%20%3FnameDepIt%20%3FnameDepEn%20%3FaltNameDepDe%20%3FaltNameDepFr%20%3FaltNameDepIt%20%3FaltNameDepEn%20%3Foffice%20%3FnameDe%20%3FnameFr%20%3FnameIt%20%3FnameEn%20WHERE%20%7B%0A%20%0A%20%20%3Foffice%20schema%3AinDefinedTermSet%20%3Chttps%3A%2F%2Fld.admin.ch%2Foffice%3E.%0A%20%20%3Foffice%20schema%3AparentOrganization%20%3Fdepartment.%0A%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3Aname%20%3FnameDe.%20FILTER(lang(%3FnameDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3Aname%20%3FnameFr.%20FILTER(lang(%3FnameFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3Aname%20%3FnameIt.%20FILTER(lang(%3FnameIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3Aname%20%3FnameEn.%20FILTER(lang(%3FnameEn)%20%3D%20%22en%22)%20%7D%0A%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3AalternateName%20%3FaltNameDe.%20FILTER(lang(%3FaltNameDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3AalternateName%20%3FaltNameFr.%20FILTER(lang(%3FaltNameFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3AalternateName%20%3FaltNameIt.%20FILTER(lang(%3FaltNameIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Foffice%20schema%3AalternateName%20%3FaltNameEn.%20FILTER(lang(%3FaltNameEn)%20%3D%20%22en%22)%20%7D%0A%20%20%0A%20%20%3Fdepartment%20schema%3AinDefinedTermSet%20%3Chttps%3A%2F%2Fld.admin.ch%2Fdepartment%3E.%0A%20%20%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepDe.%20FILTER(lang(%3FnameDepDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepFr.%20FILTER(lang(%3FnameDepFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepIt.%20FILTER(lang(%3FnameDepIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3Aname%20%3FnameDepEn.%20FILTER(lang(%3FnameDepEn)%20%3D%20%22en%22)%20%7D%0A%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepDe.%20FILTER(lang(%3FaltNameDepDe)%20%3D%20%22de%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepFr.%20FILTER(lang(%3FaltNameDepFr)%20%3D%20%22fr%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepIt.%20FILTER(lang(%3FaltNameDepIt)%20%3D%20%22it%22)%20%7D%0A%20%20OPTIONAL%20%7B%20%3Fdepartment%20schema%3AalternateName%20%3FaltNameDepEn.%20FILTER(lang(%3FaltNameDepEn)%20%3D%20%22en%22)%20%7D%0A%0A%7D%0A&endpoint=https%3A%2F%2Fld.admin.ch%2Fquery&requestMethod=POST&tabTitle=Query&headers=%7B%7D&contentTypeConstruct=text%2Fturtle&contentTypeSelect=application%2Fsparql-results%2Bjson&outputFormat=table&outputSettings=%7B%22pageSize%22%3A-1%7D
15+
```
16+
17+
It can be (re-)generated by running:
18+
19+
```bash
20+
npx run build:organisations
21+
```

0 commit comments

Comments
 (0)